I have a strange problem. I am trying to validate one form sent through POST request, and this form is in fact built on the foundation of four models.
The idea is to validate all the forms and then save them accordingly, in appropriate order, assigning foreign keys on the basis of recently saved model instances.
The problem occurs when I try to assign a value to the foreign key of the model that was properly validated through the form.is_valid()
call. It throws however an IntegrityError
saying that this specific foreign key "may not be NULL".
Below please find the code that should give you the idea on what I am doing:
Models & forms defitinions:
class Author(models.Model):
name = models.CharField(blank=False, max_length=150)
book = models.OneToOneField('Book') # its important, one author has one book
class Book(models.Model):
name = models.CharField(blank=False, max_length=150)
class AuthorForm(ModelForm):
class Meta:
model = Author
exclude = ('book',)
class BookForm(ModelForm):
class Meta:
model = Book
In one of the views:
if request.method == "POST":
author_form = AuthorForm(request.POST, prefix='author')
book_form = BookForm(request.POST, prefix='book')
if author_form.is_valid() and book_form.is_valid():
book = book_form.save()
author_form.cleaned_data['book_id'] = book.id
author.form.save() # Error!
During author_form.save()
I get error similar to this:
IntegrityError at /api/my_method
myapp_author.book_id may not be NULL
I am completely sure that book.id
is an integer (int
, I have checked it) with the ID of recently saved Book
record.
Do you have any idea how could I set the foreign key having validated & unsaved form, so I can safely save it into the database?
You've excluded book
from the AuthorForm
, so Django doesn't care what the value of cleaned_data['book_id']
is - it'll just ignore it.
Instead, you need to set the book property directly on the unsaved author instance:
book = book_form.save()
author = author.form.save(commit=False)
author.book = book
author.save()
You could try:
if author_form.is_valid() and book_form.is_valid():
book = book_form.save()
author = author_form.save(commit=False)
author.book = book
author.save()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With