2010-01-01 14 views
9

Bir nesneyi request.POST kullanarak form kümesinden nasıl güncelleyebilirim?Django formset - bir nesneyi nasıl güncellersiniz?

İşte kodum ve benim sorunum, bu her zaman yeni bir PhoneNumber nesnesi oluşturuyor olmasıdır. Ancak eski PhoneNumber nesnesini güncellemek istiyorum.

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), 
    ) 

Düzenleme:

@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),) 

Bu yaklaşım hatta her satır içi forma sil işaret kutusunu ekler:

PhoneNumberFormSet = modelformset_factory(PhoneNumber, max_num=3, extra=3, exclude=('contact',)) 

Düzenleme:: inlineformset_factory kullanarak çözüm Üç PhoneNumberForms oluşturun. Kolay ve harika.

cevap

11

Yerine modelformset_factory kullanın, inlineformset_factory kullanın - bkz the documentation here - üzgünüm, başlangıçta bunu işaret etmeliydim.

inlineformset_factory o ilgilenir beri Sonra, QuerySet şeyler bırakın ve sadece (Contact nesne yani ebeveyn modelinin atıfta burada olan) instance argüman geçmektedir. Ayrıca, tekrar ele alınması gereken iletişim özniteliğini açık bir şekilde ayarlayarak yinelemeniz gerekmez.

+0

Teşekkürler..Bu çok şey öğreniyorum :) Bu yaklaşımla da başka bir hata alıyorum: IndexError at/crm/contacts/15/ - liste endeksi aralık dışı .. umarım inlineformset_factory –

+0

Ok ile kurtulun çalışıyor gibi görünüyor. Sadece PhoneNumber nesneleri için denedim. Ve vay .. Her satır içi nesne için gerçekten güzel bir silme onay kutusu var .. wuhaa :) Ama bir soru: Inline nesnelerin bir max_num tanımlamak için bir yolu var mı? Her zaman üç tane daha satır içi eklediğinden. –

+0

Tamam, "normal" form kümeleriyle aynı çözüm. max_num = 3 veya extra = 0 –

İlgili konular