I have two models, Book
and Page
, where Page
has a foreign key relation to Book
. In admin.py, the webpage to modify a book has inline elements for Page
objects.
models.py:
class Book(models.Model):
# ...
class Page(models.Model):
book = models.ForeignKey(Book, editable=False)
number = models.IntegerField('Page number')
# ...
admin.py:
class PageAdminInline(admin.TabularInline):
model = Page
extra = 1
class BookAdmin(admin.ModelAdmin):
inlines = [PageAdminInline]
admin.site.register(Book, BookAdmin)
In the inline forms, a field allows to set the page number for each page. With this configuration, how can I validate the global condition that all pages numbers of a book should be different and numbered from one to the number of Page
objects associated to the book?
I suppose I have to override a clean()
method related to a book model or form somewhere, but I don't know how to access from there the data related to the pages that the user inputs.
Edit
Based on Emett's suggestion, I have tried to override the clean()
method of the Page
model:
class Page(models.Model):
book = models.ForeignKey(Book, editable=False)
number = models.IntegerField('Page number')
def clean():
book_pages = Page.objects.filter(book=self.book)
# ... [apply condition on the book_pages QuerySet]
super(Page, self).clean()
This does not work: if I modify the page number of all pages in the admin site for a book, book_pages
will contain objects that have the old page numbers.
In addition, having the condition checked in Page
also means that it will be tested n times if I have n pages, while just checking it once should be sufficient.
An easier solution would be putting unique_together in django model. IE
Another workaround if you don't want to use
unique_together
, then create a form, use it in inline, ie: