Search code examples
pythondjangoinline-formset

Django inlineformset does not save ForeignKey field


So i am testing a the inlineformset feature in Django, and so far have the following code:

Application name: Example

models.py

from django.db import models
from django.core.urlresolvers import reverse

class Recipe(models.Model):
    pub_date = models.DateTimeField('Date Published', auto_now_add= True)
    title = models.CharField(max_length=200)
    instruction = models.TextField()

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('recipe_edit', kwargs={'pk': self.pk})


class Ingredient(models.Model):
    recipe = models.ForeignKey(Recipe, related_name="ingredients")
    ingredient = models.CharField(max_length=255)

    def __unicode__(self):
        return self.recipe_id

    def get_absolute_url(self):
        return reverse('ingredient_edit', kwargs={'pk': self.recipe_id})

forms.py

from django import forms
from models import Recipe, Ingredient
from django.forms.models import inlineformset_factory

MAX_INGREDIENTS = 5

IngredientFormSet = inlineformset_factory(
    Recipe,
    Ingredient,
    can_delete=False,
    extra=MAX_INGREDIENTS
)


class UserSubmittedRecipeForm(forms.ModelForm):
    class Meta:
        model = Recipe
        exclude = ('pub_date',)

views.py

def recipe_create(request, template_name='example/recipe_form.html'):
    if request.POST:
        form = UserSubmittedRecipeForm(request.POST)
        if form.is_valid():
            recipe = form.save(commit=False)
            ingredient_formset = UserSubmittedRecipeForm(request.POST, instance=recipe)
            if ingredient_formset.is_valid():
                recipe.save()
                ingredient_formset.save()
                return redirect('recipe_list')
    else:
        form = UserSubmittedRecipeForm()
        ingredient_formset = IngredientFormSet(instance=Recipe())
    return render(request, template_name, {
        "form": form,
        "ingredient_formset": ingredient_formset
    }, context_instance=RequestContext(request))

Views version 2 This does not work either.

def recipe_create(request, template_name='example/recipe_form.html'):
    if request.POST:
        form = UserSubmittedRecipeForm(request.POST)
        if form.is_valid():
            created_recipe = form.save()
            ingredient_formset = UserSubmittedRecipeForm(request.POST, instance=created_recipe)
            if ingredient_formset.is_valid():
                ingredient_formset.save()
                return redirect('recipe_list')
    else:
        form = UserSubmittedRecipeForm()
        recipe = Recipe()
        ingredient_formset = IngredientFormSet(instance=recipe)
    return render(request, template_name, {
        "form": form,
        "ingredient_formset": ingredient_formset
    }, context_instance=RequestContext(request))

The problem that i am having is that the "ingredient" field from the Ingredient model is not saved every time the form is submitted.

There is no error displayed. The rest of the field from the Recipe model gets saved properly.

Does anyone know why is this?


Solution

  • Should
    ingredient_formset = UserSubmittedRecipeForm(request.POST, instance=created_recipe)
    be
    ingredient_formset = IngredientFormSet(request.POST, instance=created_recipe)?

    If that is the problem, you have made it in both views.