如何在同一模板上使用两个不同的Django表单?

如何在同一模板上使用两个不同的Django表单?,django,django-models,django-forms,django-templates,django-views,Django,Django Models,Django Forms,Django Templates,Django Views,My forms.py: class AlertForm(forms.ModelForm): class Meta: model=Alert fields = ('high','medium', 'user') widgets = { 'user': forms.HiddenInput() } AlertCountFormset = modelformset_factory(Alert,

My forms.py:

class AlertForm(forms.ModelForm):
class Meta:
    model=Alert
    fields = ('high','medium', 'user')
    widgets = {
        'user':  forms.HiddenInput()
    }

AlertCountFormset = modelformset_factory(Alert,
                                       form = AlertForm)
另一个Django表单类:

class NotifierForm(forms.ModelForm):
high = forms.ChoiceField(choices=NOTIFIER_TYPE)
medium = forms.ChoiceField(choices=NOTIFIER_TYPE)
low = forms.ChoiceField(choices=NOTIFIER_TYPE)  

def save(self, commit=True):
    alert = super(NotifierForm, self).save(commit=False)
    alert.high = self.cleaned_data["high"]
    alert.medium = self.cleaned_data["medium"]
    alert.low = self.cleaned_data["low"]
    alert.save()
    return alert

class Meta:
    model=Notifier
    fields = ('high','medium', 'low', 'user')
    widgets = {
        'user': forms.HiddenInput()
    }

NotifierFormset = modelformset_factory(Notifier,
                                    form = NotifierForm)
以下是选项字段:

NOTIFIER_TYPE = (
(0, _('E-mail')),
(1, _('Skype')),
(2, _('IRC'))
)
我想在同一个模板上填写这两张表格。因此,我选择为这两个项目编写相同的视图,即:

def profile_setting(request, slug):
if request.method == 'POST':
    alert_form = AlertForm(request.POST)
    notifier_form = NotifierForm(request.POST)
    if alert_form.is_valid() and notifier_form.is_valid():
        alert = alert_form.save(commit=False)
        notifier = notifier_form.save(commit=False) 
        alert.user = request.user.username
        notifier.user = request.user.username
        notifier.save()
        alert.save()
        return HttpResponseRedirect(reverse('profile_setting', args=[slug]))

extra_context = {
    'alert_form': AlertForm(),
    'notifier_form': NotifierForm()
}
return direct_to_template(request,'users/user_profile_setting.html',
                          extra_context)
根据my template.html中的说明:

{% block content %}
<h3>{% trans "Alerts limit" %}</h3>
<form action="" method="POST">{% csrf_token %}
    {{ alert_form.as_p }}
    <input type="submit" value="{% trans 'Update' %}" />
</form>

<h3>{% trans "Notifier setting" %}</h3>
<form action="" method="POST">{% csrf_token %}
    {{ notifier_form.as_p }}
    <input type="submit" value="{% trans 'Update' %}" />
</form>

然后,它还为notify_表单保存相同的值。为什么会发生这种情况。视图有问题吗?

问题是表单上的字段名称相同

request.POST是一个类似字典的对象。因此,它只包含请求中的名称/值对。如果两种表单上的字段名称相同,则调用

alert_form = AlertForm(request.POST)
notifier_form = NotifierForm(request.POST)
它们用相同的值初始化。要解决此问题,请使两个窗体之间的名称唯一。例如,在AlertForm上的所有字段名前面加上“alert_u3;”前缀。

使用该参数,以避免字段名冲突

例如:

alert form = AlertForm(request.POST, prefix='alert') 
notifier_form = NotifierForm(request.POST, prefix='notifier')

您需要在未绑定表单中使用相同的前缀

extra_context = { 'alert_form': AlertForm(prefix='alert'),  notifier_form': NotifierForm(prefix='notifier') }

使用前缀的优点是,您不需要手动重命名字段,正如umnik700在其答案中所建议的那样

对不起,我没抓住你。哪两个名字?谢谢你的回答:)还有一件事。在Django表单中,每当我要更新表单中的所有字段时,这是否可能。所有字段都应显示数据库中以前保存的值。是的,这是可能的。包含两个表单实例的额外上下文。他们现在的做法是传递未初始化的表单。如果你想显示数据,你需要初始化它们。除此之外,这些变化。我是否应该对模板端进行更改?不,您不需要对模板进行任何更改。添加模板后。什么都没有发生。我的意思是,数据库中没有输入值。即使没有错误,您也需要在未绑定表单(在
extra\u context
中创建)中使用与绑定到post数据的表单相同的前缀。
extra_context = { 'alert_form': AlertForm(prefix='alert'),  notifier_form': NotifierForm(prefix='notifier') }