Django formset - 如何更新对象? [英] Django formset - how to update an object?
问题描述
如何使用 request.POST
从表单集中更新对象?
How can I update an object from a formset using request.POST
?
这是我的代码,我的问题是这总是会创建一个新的 PhoneNumber
对象.但我想更新旧的 PhoneNumber
对象.
Here is my code and my problem is that this always creates a new PhoneNumber
object. But I want to update the old PhoneNumber
object.
def contact_detail(request, contact_id):
contact = get_object_or_404(Contact, pk=contact_id)
phone_number_list = PhoneNumber.objects.filter(contact=contact_id)
if request.method == 'POST':
cform = ContactForm(request.POST, instance=contact)
#the next line is probably wrong!
phonenumberformset = PhoneNumberFormSet(request.POST, queryset=phone_number_list)
if cform.is_valid() and phonenumberformset.is_valid():
phonenumber_instances = phonenumberformset.save(commit=False)
for phonenumber in phonenumber_instances:
phonenumber.contact = contact
phonenumber.save()
request.user.message_set.create(message='The contact "%s" was chanced successfully.' % contact.__str__())
return HttpResponseRedirect("/crm/contacts/?oby=1")
else:
cform = ContactForm(instance=contact)
phonenumberformset = PhoneNumberFormSet(queryset=phone_number_list)
return render_to_response(
'crm/contact_detail.html',
{'cform': cform, 'phonenumberformset': phonenumberformset,},
context_instance = RequestContext(request),
)
我创建了三个 PhoneNumberForms:
I create three PhoneNumberForms:
PhoneNumberFormSet = modelformset_factory(PhoneNumber, max_num=3, extra=3, exclude=('contact',))
使用 inlineformset_factory 的解决方案:
The solution using inlineformset_factory:
@login_required
def contact_detail(request, contact_id):
contact = get_object_or_404(Contact, pk=contact_id)
PhoneNumberInlineFormSet = inlineformset_factory(Contact, PhoneNumber, max_num=3)
if request.method == 'POST':
cform = ContactForm(request.POST, instance=contact)
classificationformset = ClassificationInlineFormSet(request.POST, request.FILES, instance=contact)
addressformset = AddressInlineFormSet(request.POST, request.FILES, instance=contact)
phonenumberformset = PhoneNumberInlineFormSet(request.POST, request.FILES, instance=contact)
if cform.is_valid() and phonenumberformset.is_valid():
contact = cform.save()
phonenumberformset.save()
request.user.message_set.create(message='The contact "%s" was chanced successfully.' % contact.__str__())
return HttpResponseRedirect("/crm/contacts/?oby=1")
else:
cform = ContactForm(instance=contact)
phonenumberformset = PhoneNumberInlineFormSet(instance=contact)
return render_to_response(
'crm/contact_detail.html',
{'cform': cform, 'phonenumberformset': phonenumberformset,},
context_instance = RequestContext(request),)
这种方法甚至为每个内联表单添加了一个删除复选框.简单而伟大.
This approach even adds a delete checkbox to each inline form. Easy and great.
推荐答案
与其使用 modelformset_factory
,不如使用 inlineformset_factory
- 参见 此处的文档 - 抱歉,最初应该向您指出这一点.
Rather than use modelformset_factory
, use inlineformset_factory
- see the documentation here - sorry, should have pointed you to that initially.
然后你可以删除 queryset 的东西,因为 inlineformset_factory 会处理这个,只需传递 instance
参数(这里指的是 父模型,即 <代码>联系人代码>对象).您也不需要在保存时显式设置 contact 属性,因为这已经被处理了.
Then you can drop the queryset stuff, since inlineformset_factory takes care of that, and just pass the instance
argument (which here refers to the parent model, ie the Contact
object). You also won't need to iterate through explicitly setting the contact attribute on save, as again that's taken care of.
这篇关于Django formset - 如何更新对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!