python Django 表单集:首先需要制作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2406537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django formsets: make first required?
提问by mpen
These formsets are exhibiting exactly the oppositebehavior that I want.
这些表单集表现出与我想要的完全相反的行为。
My view is set up like this:
我的观点是这样设置的:
def post(request): # TODO: handle vehicle formset
VehicleFormSetFactory = formset_factory(VehicleForm, extra=1)
if request.POST:
vehicles_formset = VehicleFormSetFactory(request.POST)
else:
vehicles_formset = VehicleFormSetFactory()
And my template looks like this:
我的模板如下所示:
<div id="vehicle_forms">
{{ vehicles_formset.management_form }}
{% for form in vehicles_formset.forms %}
<h4>Vehicle {{forloop.counter}}</h4>
<table>
{% include "form.html" %}
</table>
{% endfor %}
</div>
That way it initially generates only 1 form, like I want. But I want that one form to be required!
这样它最初只生成一种形式,就像我想要的那样。但我希望需要一种形式!
When I dynamically add blank forms with JavaScript and vehicles_formset.empty_form
all those extra forms are required, which I don't want.
当我使用 JavaScript 动态添加空白表单时,vehicles_formset.empty_form
所有这些额外的表单都是必需的,这是我不想要的。
From the docs:
从文档:
The formset is smart enough to ignore extra forms that were not changed.
表单集足够智能,可以忽略未更改的额外表单。
This is the behavior the first form is exhibiting (not what I want) but not the behavior that the extra forms are exhibiting (what I do want).
这是第一个表单展示的行为(不是我想要的),但不是额外表单展示的行为(我想要的)。
Is there some attribute I can can change to at least make oneform required?
是否有一些我可以更改的属性以至少使一个表单成为必需?
回答by mpen
Found a better solution:
找到了更好的解决方案:
class RequiredFormSet(BaseFormSet):
def __init__(self, *args, **kwargs):
super(RequiredFormSet, self).__init__(*args, **kwargs)
for form in self.forms:
form.empty_permitted = False
Then create your formset like this:
然后像这样创建你的表单集:
MyFormSet = formset_factory(MyForm, formset=RequiredFormSet)
I reallydon't know why this wasn't an option to begin with... but, whatever. It only took a few hours of my life to figure out.
我真的不知道为什么这不是一个开始的选择……但是,无论如何。我只用了几个小时就搞清楚了。
This will make all the forms required. You could make just the first one required by setting self.forms[0].empty_permitted
to False
.
这将制作所需的所有表格。您可以通过设置self.forms[0].empty_permitted
为 来制作所需的第一个False
。
回答by Anentropic
New in Django 1.7: you can specify this behaviour with your formset_factory
Django 1.7 中的新功能:您可以使用 formset_factory 指定此行为
https://docs.djangoproject.com/en/1.8/topics/forms/formsets/#validate-min
https://docs.djangoproject.com/en/1.8/topics/forms/formsets/#validate-min
VehicleFormSetFactory = formset_factory(VehicleForm, min_num=1, validate_min=True, extra=1)
回答by mpen
Well... this makes the first form required.
嗯...这需要第一个表格。
class RequiredFormSet(BaseFormSet):
def clean(self):
if any(self.errors):
return
if not self.forms[0].has_changed():
raise forms.ValidationError('Please add at least one vehicle.')
Only "problem" is that if there are 0 forms, then the clean
method doesn't seem to get called at all, so I don't know how to check if there are 0. Really...this should never happen though (except that my JS has a bug in it, allowing you to remove allthe forms).
唯一的“问题”是,如果有 0 个表单,那么该clean
方法似乎根本没有被调用,所以我不知道如何检查是否有 0 个。真的……这应该永远不会发生(除了我的 JS 中有一个错误,允许您删除所有表单)。
回答by Wogan
Oh I think I see. Try this:
哦,我想我明白了。试试这个:
from django.forms.formsets import BaseFormSet, formset_factory
class OneExtraRequiredFormSet(BaseFormSet):
def initial_form_count(self):
return max(super(OneExtraRequiredFormSet,self).initial_form_count() - 1,0)
VehicleFormSetFactory = formset_factory(VehicleForm, formset=OneExtraRequiredFormSet, extra=1)
== Original answer below ==
==下面的原始答案==
When you say "at least make one form required", I assume you mean "make only one extra form required, regardless of how many have been added via javascript".
当您说“至少需要一个表单”时,我假设您的意思是“只需要一个额外的表单,无论通过 javascript 添加了多少表单”。
You will need to have hidden input on your page which contains the number of forms that have been added via javascript, and then use that number, minus 1, as the value to pass in as the extra
attribute to your formsets constructor.
您需要在页面上隐藏输入,其中包含通过 javascript 添加的表单数量,然后使用该数字减去 1 作为值作为extra
属性传递给您的表单集构造函数。