In models.py

class Recipes(models.Model): name = models.CharField(max_length=200) autor = models.ForeignKey(User) date = models.DateTimeField(auto_now=True) text = models.TextField(max_length=5000) class Products(models.Model): name = models.CharField(max_length=200) text = models.TextField(max_length=5000) def __unicode__(self): return self.name class ProductsInRecipes(models.Model): product = models.ForeignKey(Products) recipe = models.ForeignKey(Recipes) weight = models.PositiveIntegerField( validators=[MaxValueValidator(10000)], blank=False, null=False) 

In forms.py

 # -*- coding: utf-8 -*- from django import forms from recipes.models import Recipes, ProductsInRecipes class RecipesAddForm(forms.ModelForm): class Meta: model = Recipes fields = ('name', 'text') class ProductsInRecipesForm(forms.ModelForm): class Meta: model = ProductsInRecipes fields = ('product', 'weight') 

In views.py

 # -*- coding: utf-8 -*- from django.shortcuts import render_to_response, redirect from django.core.context_processors import csrf from django.template import RequestContext from django.forms.formsets import formset_factory from recipes.forms import RecipesAddForm, ProductsInRecipesForm def add(request): args = {} args.update(csrf(request)) args['form'] = RecipesAddForm() args['form2'] = formset_factory( ProductsInRecipesForm, extra=2, max_num=30, validate_max=True) if request.POST: form = RecipesAddForm(request.POST) ProuctsFormSet = formset_factory(ProductsInRecipesForm) form2 = ProuctsFormSet(request.POST) args['form'] = form args['form2'] = form2 if form.is_valid() and form2.is_valid(): recipe = form.save(commit=False) recipe.autor = request.user recipe.save() form.save_m2m() for product in form2: product.save(commit=False) product.recipe = recipe product.save() return redirect('/ok/') return render_to_response('recipes_add.html', args, RequestContext(request)) return render_to_response('recipes_add.html', args, RequestContext(request)) 

And the recipes_add.html template

 {% extends "main.html" %} {% block content %} <div id="content" class="lr_auto"> <form id="add_recipes_form" method="post" action="/recipes/add/"> {% csrf_token %} {{form}} {% for form in form2 %} {{form.product}} {{form.weight}} {% endfor %} {{form2.management_form}} <input type="submit" value="Добавить"> </form> </div> {% endblock content %} 

Clicking on submit error: NOT NULL constraint failed: productsInRecipes.recipe_id

The data from the form is saved, but from form2, respectively, it does not. How to save form2 correctly or what am I doing wrong?

  • one
    Well, judging by the error, the problem seems to be that you have recipe = models.ForeignKey (Recipes) in ProductsInRecipes, and this field is not filled in in ProductsInRecipesForm. - Denis
  • product.recipe = recipe But isn’t that enough? I also tried product.recipe = 1 and substitute other values ​​... - roffl
  • Is it really in the product model? Is there a recipe box? - Denis
  • product from ProductsInRecipes, there is a recipe - roffl
  • I agree, I did not look carefully. form.save_m2m() this form.save_m2m() string exactly correct? - Denis

1 answer 1

If I understand everything correctly, the problem is in this piece of code

product.save(commit=False)

where do you save the result? it weighs you in the air, respectively, then you no longer work with the model object, but with the same form:

 product.recipe = recipe product.save() 

Learn to correctly form variable names and there will be no such problems:

 for product_form in form2: product = product_form.save(commit=False) product.recipe = recipe product.save() 
  • Thank you for help! Of course, during this time I solved the problem a little differently, removing the intermediate model in general, but for the future it will be an excellent lesson for me. Your decision is the right one. - roffl