首页 > 解决方案 > 从 Django 中的两个视图发送回表单

问题描述

我正在制作一个项目,该项目涉及用户能够在表单中编写,然后将其保存为降价文件。我需要找到一种方法向用户展示他当前正在编写的降价代码在解析后看起来如何;这将显示在一个单独的静态页面上,并带有一个返回按钮以返回写作。

最后一部分给我带来了问题,因为我设法向用户展示了他的文件的外观,但我还没有找到一种方法将它呈现回它来自的原始输入表单

预览 HTML

{% extends "encyclopedia/layout.html" %}

{% block title %}
    Encyclopedia
{% endblock %}

{% block body %}
    <h1>Preview</h1>

    <h3>{{title}}</h3>
    <hr>
    
    {{preview|safe}}

    <form action="{% url 'new_entry' %}" method="POST">
        {% csrf_token %}
        <input type="submit" name="return" value="Return">
    </form>

{% endblock %}

新条目 HTML


{% block title %}
    Encyclopedia
{% endblock %}

{% block body %}
    <h1>New Entry</h1>
    <div class="form-group">
        <form action="{% url 'new_entry' %} " method="POST">
            {{form.as_table}}
            {% csrf_token %}
            <input type="submit" value="Save" name="submit">
            <input type="submit" value="Preview" name="preview">
        </form>
    </div>
{% endblock %}

预览和新 HTML 的视图

def preview(request):
    #Retrieve data from the request
    form = EntryForm(request.POST)
    if form.is_valid():
        title = form.cleaned_data['title']
        body = form.cleaned_data['body']

    # Nonfunctioning part
    #It's supposed to return the request to the original function
    #and letting it know that it has to pre-populate the form
    if 'return' in request.POST:
        return new_entry(request, fill_form=True)

    #Render the contents of the form
    return render(request, "encyclopedia/entry_preview.html",
    {"title":title,"preview":body})


def new_entry(request, fill_form = False): 

    #Non functioning part
    #Supposedly should get the request that the view 'preview'
    #recieved and get the form from there
    form = EntryForm()
    if fill_form is True:
        form = EntryForm(request.POST)

    if form.is_valid():
        title = form.cleaned_data['title']
        body = form.cleaned_data['body']

    #If form returned submit then save the file
    if 'submit' in request.POST:
        util.save_entry(title,body)     
        return redirect(reverse('new_entry'))
    #If form returned preview then call function to display
    #users input rendered correctly     
    elif 'preview' in request.POST:
        #Pass the POST request to this other function
        return preview(request)
    #Else just render an empty form
    else:   
        return render(request,'encyclopedia/new_entry.html',
        {'form':form})

表单基于模型,它只包含两个基本字段,titlebody.

无论哪种方式都可以接受其他想法来处理这个问题,我的问题主要是当函数preview被调用时,它会渲染传递的值,但现在传递的参数已经消失了,无法返回new_entry视图。另外,我想通过 URL 传递数据,但正文可能有数千个单词长。

标签: pythonhtmldjangodjango-viewsdjango-forms

解决方案


跟进评论,我将简要解释解决此问题的一种方法。对于这个任务,我将使用一个非常小的 django 库,称为django_htmx。看看htmx的用法,不到十分钟你就可以轻松实现它了。您的表单将如下所示:

<form action="{% url 'new_entry' %}" 
      data-hx-post="{% url 'new_entry' %}" 
      data-hx-target="#your-container-id"
      data-hx-swap="innerHTML"
      method="POST">
      {{form.as_table}}
      {% csrf_token %}
      <input type="submit" value="Save" name="submit">
      <input type="submit" value="Preview" name="
</form>

data-hx-post指定通过 ajax 发布此表单的 url。并data-hx-target指定将来自 ajax 请求的响应插入的容器。data-hx-swap告诉 htmx 将响应插入到该容器中。

将您的encyclopedia/entry_preview.html模板放在包含块中。并将其包含在与表单相同的页面中。不要忘记给容器元素一个 ID,以便您可以在 htmx 中使用data-hx-target. 在您的视图功能中,您可以说:

def new_entry(request, fill_form = False): 
    if request.method == "POST":
        if request.htmx:
            # The request is made with htmx ajax call...
            # So we render only one side of the page. The display side.
            return render(request, "encyclopedia/entry_preview.html",
                         {"title":title,"preview":body})
       else:
          #render the page normally here. both with form and with preview container.

试一试,问问你是否被卡住了。您将拥有一个不错的动态降价编辑页面。

PS:您可以使用data-hx-trigger它来制作它,即使在打字时它也会更新。就像 Stackoverflow 一样。:)


推荐阅读