Jeremy
Jeremy

Reputation: 2536

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?

Upvotes: 0

Views: 445

Answers (2)

neRok
neRok

Reputation: 1005

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.

Upvotes: 1

gmfreak
gmfreak

Reputation: 399

There was a typo in version 2 of views. Check whether this solves your problem

Views.py version 2:

   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()
            #There was a typo here
            ingredient_formset = IngredientFormSet(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))

Upvotes: 1

Related Questions