从 Django 中的两个视图发回表单

Send Form back and from two views in Django

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

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

预览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 被调用时,它呈现传递的值但现在传递的参数消失了,我无法return 到 new_entry 视图。 另外,我想通过 URL 传递数据,但正文可能有数千个字。

根据评论,我将简要说明一种解决此问题的方法。对于这个任务,我将使用一个非常小的 django 库,称为 django_htmx. Just take a look at the usage of 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 到 post 这种形式。 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使其在输入时更新。就像 Whosebug 一样。 :)