在Django admin

时间:2017-01-04 00:37:46

标签: django django-admin django-validation

我有两个模型BookPage,其中PageBook具有外键关系。在admin.py中,修改图书的网页包含Page个对象的内联元素。

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)

在内联表单中,字段允许设置每个页面的页码。使用此配置,如何验证全局条件,即书籍的所有页面编号应该不同,并从1编号到与书籍关联的Page个对象的数量?

我想我必须覆盖与书籍模型或某个地方相关的clean()方法,但我不知道如何从那里访问与用户输入的页面相关的数据。< / p>

修改

根据Emett的建议,我试图覆盖clean()模型的Page方法:

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()

这不起作用:如果我修改管理网站中所有页面的页码,book_pages将包含具有旧页码的对象。

此外,在Page中检查条件也意味着如果我有n页,它将被测试n次,而只检查一次就足够了。

1 个答案:

答案 0 :(得分:0)

更简单的解决方案是将unique_together放在django模型中。 IE

class Page(models.Model):
    book = models.ForeignKey(Book, editable=False)
    number = models.IntegerField('Page number')

    class Meta:
        app_label = 'page'
        db_table = 'pages'
        verbose_name = 'Page'
        verbose_name_plural = 'Pages'
        unique_together = (('book', 'number'),)

如果您不想使用unique_together,然后创建表单,在内联中使用它,则另一种解决方法,即:

class PageForm(forms.ModelForm):
   class Meta:
     model = Page
     fields ='__all__'

   def clean():
       cleaned_data = self.cleaned_data
       book = cleaned_data.get('book')
       number = cleaned_data.get('number')
       page_qset = Page.objects.filter(book=book, number=number)

       if len(page_qset) > 0:  # inefficient solution, using it for forcibly executing query
             raise forms.ValidationError('Already exists')
       return super().clean()



class PageAdminInline(admin.TabularInline):
    form = PageForm