10

This is probably a fairly simple question, but I can't seem to figure it out from the Django Docs. I'm trying to save a two ModelForms at once with one being a ForeignKey of another. I'm not sure how to write the logic in the views to ensure these go together properly.

models.py

class Address(models.Model):
    address = models.CharField(max_length=100)
    city = models.CharField(max_length=50)
    zipcode = models.PositiveIntegerField()

class Store(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=140, blank=True)
    address = models.ForeignKey(Address, null=True)

forms.py

class CreateStore1Form(forms.ModelForm):
    class Meta:
        model = Store
        exclude = ('address',)

class CreateStore2Form(forms.ModelForm):
    class Meta:
        model = Address

views.py

@login_required
def create(request):
    if request.method == "POST":
        form1 = CreateStore1Form(request.POST)
        form2 = CreateStore2Form(request.POST)
        if form1.is_valid() and form2.is_valid():
            store = form1.save(address)
            new_address = form2.save(commit=False)
            new_address.store = store
            mew_address.save()
    else:
        form1 = CreateStore1Form()
        form2 = CreateStore2Form()
    return render(request, 'create.html', locals())

Any help would be appreciated. Thanks!

Sahas Katta
  • 1,596
  • 3
  • 13
  • 23
  • 2
    Does this help [Proper way to handle multiple forms on one page in Django](http://stackoverflow.com/questions/1395807/proper-way-to-handle-multiple-forms-on-one-page-in-django) – César Jul 24 '12 at 21:17
  • 1
    Did some of the answers help you? – Thomas Kremmel Jul 29 '12 at 21:30
  • 1
    For the sake of all active StackOverflow users, if you get a solution that works, please mark the answer as accepted, so that people don't spend time answering if answer is not needed anymore. – Thomas Kremmel Aug 01 '12 at 06:49
  • I was still running into an issue. I'll update this thread with a solution or mark a working answer. Sorry for leaving this thread open for so long. – Sahas Katta Aug 06 '12 at 01:50

1 Answers1

19

Django provides inline formsets for this use case:

Inline formsets is a small abstraction layer on top of model formsets. These simplify the case of working with related objects via a foreign key.

forms.py

class AddressForm(forms.ModelForm):
    class Meta:
        model = Address

class StoreForm(forms.ModelForm):
    class Meta:
        model = Store
        exclude = ('address',)

views.py

from django.forms.models import inlineformset_factory

@login_required
def create(request):    
    AddressInlineFormSet = inlineformset_factory(Address, Store, form=AddressForm)

     if request.method == 'POST':
         storeForm = StoreForm(request.POST)

         if storeForm.is_valid():
             new_store = storeForm.save()
             addressInlineFormSet = AddressInlineFormSet(request.POST, request.FILES, instance=new_store)

             if addressInlineFormSet.is_valid():
                addressInlineFormSet.save()
                return HttpResponseRedirect(reverse('some_happy_customer_url'))

             else:
                classificationformset = ClassificationInlineFormSet(request.POST, request.FILES, instance=new_store)
     else:
          addressInlineFormSet = AddressInlineFormSet()
          storeForm = StoreForm()
     return render(request, 'create.html', locals())

Please see also this question for more details.

Community
  • 1
  • 1
Thomas Kremmel
  • 13,615
  • 21
  • 104
  • 169