Django formset - 如何更新对象? [英] Django formset - how to update an object?

查看:100
本文介绍了Django formset - 如何更新对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用 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.

然后你可以放弃查询的东西,因为inlineformset_factory照顾这个,只是传递实例参数(这里引用父模型,即联系人对象)。您也不需要在保存中明确设置联系人属性来重复执行,因为再次受到保护。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆