另一种解决方案可能是使用 django 信号。
Django 将pre_save
在保存任何模型之前发送一个信号,因此您可以挂钩一个函数来对其做出反应并执行您的检查。
类似于(以@Eliot Berriot 解决方案为基础):
from django.db.models.signals import pre_save
from django.core.exceptions import ValidationError
def validate_num_books(sender, **kwargs):
if isinstance(sender, Student):
max_books = 3
elif isinstance(sender, Employee):
max_books = 30
books_count = sender.books.all().count()
if books_count >= max_books:
raise ValidationError("This person has too much books !")
pre_save.connect(validate_num_books, sender=Employee, dispatch_uid='validate_num_books')
pre_save.connect(validate_num_books, sender=Student, dispatch_uid='validate_num_books')
笔记:
我不确定 ValidationError 是否会产生预期的效果。希望绕过正在保存的模型就足够了,但也许它并不能完全那样工作,或者在某些情况下会这样做,或者在其他情况下不会......将此片段视为实验性伪代码。
正如您可能已经从上面的观点猜到的那样,我不习惯信号,而且仍然有点厌倦这些信号。这可能完全没问题,但如果出现更清洁的解决方案,我可能会选择它并完全避免信号。越简单通常越好。
与艾略特的回答相比,我可以看到这个解决方案的唯一优势是它避免了继承,正如他所说,这会导致性能问题。但是,如果您避免在父类上定义字段,我认为您应该没问题。
如果您决定尝试信号,请从这里开始。