【问题标题】:Having two different forms in a Django template在 Django 模板中有两种不同的形式
【发布时间】:2025-11-24 09:50:02
【问题描述】:

在我的项目中,我有一个模板,我试图在其中为不同的用例放置两个表单。我以前从来没有遇到过这个问题,所以我真的不知道从哪里开始在同一个页面中使用两个表单。

起初我想创建另一个视图来处理每个表单,但我认为这个解决方案会在我的模板呈现方面产生问题,如果我应该再次使用另一个模板出现这个问题,则不可持续。

经过一些研究,我找到了一个解决方案,但它适用于基于类的视图,但我想避免这种情况,因为我的视图已经是基于函数的视图,我必须在我的代码。但是,如果 CBV 是最好的选择,我可以做出改变。

每一个建议都值得赞赏

第一个字段

class FirstForm(forms.ModelForm):

    firstfield = forms.CharField() 
    secondfield = forms.CharField()
    class Meta:
        model = MyModel
        fields = ("firstfield", "secondfield")
    def save(self, commit=True):
        send = super(FirstForm, self).save(commit=False)
        if commit:
            send.save()
        return send**

第二种形式

class SecondForm(forms.ModelForm):

    firstfield = forms.FloatField() 
    secondfield = forms.Floatfield()
    thirdfield = forms.CharField()

    class Meta:
        model = MyModelTwo
        fields = ("firstfield", "secondfield", "thirdfield")

    def save(self, commit=True):
        send = super(SecondForm, self).save(commit=False)
        if commit:
            send.save()
        return send

模板

  <h3> First Form </h3>
  <form method="post" novalidate>
      {% csrf_token %}
      {% include 'main/includes/bs4_form.html' with form=form %}
      <button type="submit" class="btn btn-danger" style="background-color: red;">SUBMIT</button>
  </form>

  <h3> Second Form </h3>
  <form method="post" novalidate>
      {% csrf_token %}
      {% include 'main/includes/bs4_form.html' with form=form %}
      <button type="submit" class="btn btn-danger" style="background-color: red;">SUBMIT</button>
  </form>

views.py

def myview(request):

    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = FirstForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            send = form.save()
            send.save()
            messages.success(request, f"Success")

    # if a GET (or any other method) we'll create a blank form
    else:
        form = FirstForm()

    return render(request,
                  "main/mytemplate.html",
                  context={"form":form})

有人告诉我在我的视图中使用上下文,但我不知道如何将它集成到我的视图中。这是一个可行的解决方案,还是有更好的方法来做到这一点?

context = {
        'first_form': TradingForm(request.POST or None),
        'second_form': LimitSellForm(request.POST or None),
    }

【问题讨论】:

  • 你能解释一下你的用例是什么吗?您的问题不清楚您希望使用拖车表单实现什么目标。
  • @DanielHolmes 基本上我正在添加另一个字段,该字段在两种形式中的每一种中都会有所不同。因此,一种形式将用于触发某个任务,另一种形式将用于执行另一个不同的任务
  • 你说一个表单会触发某个任务是什么意思?如果用户填写一个表单,视图应该以一种方式处理它,如果他们填写另一个表单,视图将用另一种方式处理它?
  • 没错。它应该像这样工作

标签: python django django-models django-forms django-templates


【解决方案1】:

这是一种方法。为您的按钮添加name 属性,如下所示:

<button name="button1" type="submit" class="btn btn-danger" style="background-color: red;">SUBMIT</button>
...
<button name="button2" type="submit" class="btn btn-danger" style="background-color: red;">SUBMIT</button>

然后在你的视图中,你可以通过在帖子中查找按钮名称来检查提交了哪个表单:

def myview(request):
    if request.method == 'POST':
        if 'button1' in request.POST:
            form1 = FirstForm(request.POST)
            if form1.is_valid():
                # do what needs to be done and redirect
        if 'button2' in request.POST:
            form2 = form = SecondForm(request.POST)
            if form2.is_valid():
                # do what needs to be done and redirect
    else:
        form1 = FirstForm()
        form2 = SecondForm()

    return render(request, "main/mytemplate.html", 
                  context={'form1': form1, 'form2': form2})

【讨论】:

  • 感谢您的帮助!事实上,检查表单是从哪个按钮提交的是最有效的方法。最后一件事:我一直在对基于类的视图进行一些研究。对于这项特定任务,CBV 是更好的解决方案,还是两者都等效?
  • IMO 对此用例的基于功能的视图是最合适的,尤其是当它偏离具有单一形式的常规视图类型时。但是可以使用基于类的视图来做到这一点。
  • 是的,对不起!我是 AFK :)
【解决方案2】:

您可以使用 TemplateView 代替普通视图功能并在下面添加此功能

 def get_context_data(self, **kwargs):
        context = {
        'first_form': TradingForm(request.POST or None),
        'second_form': LimitSellForm(request.POST or None),
         }

您可以查看文档: https://docs.djangoproject.com/en/2.2/ref/class-based-views/base/#templateview

【讨论】:

  • OP 说他们希望避免使用基于类的视图
最近更新 更多