我创建的视图,其返回包括接触形式和两个PHONE_NUMBER形式形式,以下这个例子中直列形式,才需要:django的内联编辑如果至少一个字段被填充了
的只有当用户在电话号码表格中插入至少一个字段的值时,才能验证电话号码表单。例如:电话号码有一个类型和一个号码。如果用户选择类型,则该号码是必需的。
现在我想知道如何在视图中检查用户是否插入了值/选定的类型或插入了一个数字。它应该像管理员一样工作,用于内联编辑模型。
我的看法是这样的:首先如下响应之后
def contact_add(request):
user = request.user
if request.method == 'POST':
cform = ContactForm(request.POST)
pforms = [PhoneNumberForm(request.POST, prefix=str(x)) for x in range(0,3)]
if cform.is_valid() and all([pf.is_valid() for pf in pforms]):
new_contact = cform.save(commit=False)
new_contact.created_by = user
new_contact.save()
for pf in pforms:
new_phone_number = pf.save(commit=False)
new_phone_number.contact = new_contact
new_phone_number.save()
request.user.message_set.create(message='Contact %s has been added.' % new_contact.__str__())
return HttpResponseRedirect("/crm/contacts/?oby=1")
else:
cform = ContactForm()
pforms = [PhoneNumberForm(prefix=str(x)) for x in range(0,3)]
return render_to_response(
'crm/contact_add.html',
{'cform': cform, 'pforms': pforms,},
context_instance = RequestContext(request),
)
编辑:
我试图实现与自定义验证这个任务,但没来一个令人满意的结束。为了缓解我的任务,我改变了一些用例。我创建了一个包含一个联系表和一个地址表的表单。只有填写了地址表单中的至少一个字段时,才能验证地址表单,因为应该可以在不创建相应地址的情况下创建联系人。
首先,我试图用custome验证,这是这样的:
class AddressForm(forms.ModelForm):
class Meta:
model = Address
exclude = ('contact',)
def clean(self):
cleaned_data = self.cleaned_data
street = cleaned_data.get("street")
postal_code = cleaned_data.get("postal_code")
city = cleaned_data.get("city")
country = cleaned_data.get("country")
if not street and not postal_code and not city and not country:
#searching a better idea here
return 0
else:
return cleaned_data
但是,这并不能真正帮助,因为这样一来我不摆脱验证错误。
这使我想到,干净的方法是做错误的地方做这个验证,我想我必须检查POST.request中是否所有地址表单的值都丢失。如果他们错过了,我不会为地址表单调用is_valid(),而忽略它。如果至少有一个值可用,我只需执行地址表单的常规验证,而不必重写clean()方法。
好的或坏的主意? 如果这是一个好主意,我怎样才能轻松地检查POST请求的地址表单的值。
也许我真的思维方式复杂:-)
编辑:该解决方案使用表单集:
@login_required
def contact_add(request):
user = request.user
if request.method == 'POST':
cform = ContactForm(request.POST)
phonenumberformset = PhoneNumberFormSet(request.POST)
if cform.is_valid() and classificationformset.is_valid() and addressformset.is_valid() and phonenumberformset.is_valid():
new_contact = cform.save(commit=False)
new_contact.created_by = user
new_contact.save()
new_phonenumber_instances = phonenumberformset.save(commit=False)
for new_phonenumber in new_phonenumber_instances:
new_phonenumber.contact = new_contact
new_phonenumber.save()
request.user.message_set.create(message='Contact %s has been added.' % new_contact.__str__())
return HttpResponseRedirect("/crm/contacts/?oby=1")
else:
cform = ContactForm()
#By default, when you create a formset from a model, the formset will use
#a queryset that includes all objects in the model (e.g., Author.objects.all()).
#Here we want to present an empty formset in order to add a new object
phonenumberformset = PhoneNumberFormSet(queryset=PhoneNumber.objects.none())
return render_to_response(
'crm/contact_add.html',
{'cform': cform, 'phonenumberformset': phonenumberformset,},
context_instance = RequestContext(request),
)
请注意,这也可以实现使用inlineformset_factory,看到我的其他职位更多详细信息:link
请注意,如果您使用FormSets,则必须在模板中为每个form_set包含一个management_form。 docs
否则,你得到这个错误:
[u'ManagementForm data is missing or has been tampered with']
Using a formset inside a view is as easy as using a regular Form class. The only thing you will want to be aware of is making sure to use the management form inside the template.
{{ context.phonenumberformset.management_form }}
Formsets?从来没有听说过。将尝试它。听起来不错:-) – 2010-01-01 13:20:18
但是对于我上面的用例,如果我为一个地址表单创建一个Formset。 formset会检查用户是否填充了数据并且不会验证它? – 2010-01-01 13:26:48
好吧,它的工作。将尝试其他内联,并在我的问题中发布结果! – 2010-01-01 14:17:45