【问题标题】:How to create multiple forms in one/single page in Django?如何在 Django 的一个/单个页面中创建多个表单?
【发布时间】:2019-09-05 02:30:10
【问题描述】:

我想在我的页面中有 2 种不同的表单。但是当我尝试保存表单的值时,它们只保存在 form_fridge 中。我认为它存在,因为我将一个 csrf_token 用于 2 种形式。你能帮帮我吗?

    <form method="POST" enctype="multipart/form-data" id = "formTv">
    {% csrf_token %}
    {{ form_tv.as_p }}
    <button type="submit" class="save btn btn-default">Save</button>
    </form>

    <form method="POST" enctype="multipart/form-data" id = "formFridge">
    {% csrf_token %}
    {{ form_fridge.as_p }}
    <button type="submit" class="save btn btn-default">Save</button>
    </form>

views.py

def add_new(request):
    form_fridge = FridgeForm(request.POST, request.FILES, use_required_attribute=False)
    form_tv = TvForm(request.POST, request.FILES, use_required_attribute=False)
    if form_fridge.is_valid() and request.method == 'POST':
        form_fridge.save()
        return redirect('new')
    elif form_tv.is_valid() and request.method == 'POST':
        form_tv.save()
        return redirect('new')
    return render(request, 'appliances/add_new.html', {'form_tv': form_tv,
                                                       'form_fridge': form_fridge})

【问题讨论】:

标签: python html django django-forms


【解决方案1】:

问题是您有两个单独的 HTML &lt;form&gt; 元素和提交按钮。如果您希望同时提交和处理两个表单,它们需要位于同一个表单元素中。

<form method="POST" enctype="multipart/form-data" id = "formTv">
{% csrf_token %}
{{ form_tv.as_p }}

{{ form_fridge.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>

在视图中实例化表单时,您可能还想使用 prefix 参数,以避免名称相似的字段发生冲突。

【讨论】:

  • 不,我需要两个表格,因为用户可以看到其中一个表格。他选择他们要填写的表格。
  • 不错的答案我不知道前缀。
【解决方案2】:

您应该添加一个隐藏字段,以区分提交的表单。

<form method="POST" enctype="multipart/form-data" id = "formTv">
    {% csrf_token %}
    {{ form_tv.as_p }}
    <input type="hidden" id="form_type" name="form_type" value="form_tv">
    <button type="submit" class="save btn btn-default">Save</button>
    </form>

    <form method="POST" enctype="multipart/form-data" id = "formFridge">
    {% csrf_token %}
    {{ form_fridge.as_p }}
    <input type="hidden" id="form_type" name="form_type" value="form_fridge">
    <button type="submit" class="save btn btn-default">Save</button>
    </form>

所以当其中一个表单被提交时,你可以找到提交了哪个表单。

#views.py
def add_new(request):
    if request.method == "POST":  #check if the request is POST call or not.
        form_type = request.POST.get("form_type")
        form = None
        # check which form to evaluate
        if form_type == "form_fridge":
            form = FridgeForm(request.POST, request.FILES, use_required_attribute=False)

        if form_type == "form_tv":
            form = TvForm(request.POST, request.FILES, use_required_attribute=False)

        # evaluate the form
        if form and form.is_valid():
            form.save()
            return redirect('new')

    return render(request, 'appliances/add_new.html', {'form_tv': form_tv,
                                                       'form_fridge': form_fridge})

【讨论】:

    【解决方案3】:

    假设你有两种形式:

    class ContactForm(forms.Form):
        title = forms.CharField(max_length=150)
        message = forms.CharField(max_length=200, widget=forms.TextInput)
    
    
    class SubscriptionForm(forms.Form):
        email = forms.EmailField()
    

    Django FormView 是以这种方式处理表单的主要类。 至少,它需要:

    一个 form_class 属性,它指向我们的表单类 想要处理。

    一个 success_url 属性,用于指示重定向到哪个 URL 表单处理成功。

    执行实际处理逻辑的 form_valid 方法。

    所以在你看来:

    class MultipleFormsDemoView(MultiFormsView):
        template_name = "pages/cbv_multiple_forms.html"
        form_classes = {'contact': ContactForm,
                        'subscription': SubscriptionForm,
                        }
    
        success_urls = {
            'contact': reverse_lazy('contact-form-redirect'),
            'subscription': reverse_lazy('submission-form-redirect'),
        }
    
        def contact_form_valid(self, form):
            'contact form processing goes in here'
    
        def subscription_form_valid(self, form):
            'subscription form processing goes in here'
    

    在您的模板上:

    <form method="post">{% csrf_token %}
        {{ forms.subscription }}
        <input type="submit" value="Subscribe">
    </form>
    <form method="post">{% csrf_token %}
        {{ forms.contact }}
        <input type="submit" value="Send">
    </form>
    

    You might also want to check inline forms

    【讨论】:

      猜你喜欢
      • 2011-07-16
      • 1970-01-01
      • 2011-08-16
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      • 1970-01-01
      • 2014-12-02
      相关资源
      最近更新 更多