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

查看:17
本文介绍了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.

然后你可以删除 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屋!

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