我有一个看起来像这样的模型:
class Passenger(models.Model):
name = models.CharField(max_length=50)
surname = models.CharField(max_length=50)
class Flight(models.Model):
capacity = models.IntegerField()
passengers = models.ManyToManyField(Passenger)
在将新乘客添加到航班之前,我想验证乘客数量是否不会超过容量。我想知道最好的方法是什么。
显然我可以在添加新乘客之前手动检查乘客数量,但也许在django有一些支持?我尝试编写验证器,但不知道该怎么做。
答案 0 :(得分:0)
覆盖模型上的clean
方法以进行所需的检查:
class Passenger(models.Model):
name = models.CharField(max_length=50)
surname = models.CharField(max_length=50)
def clean(self, *args, **kwargs):
# clean gets called automatically by other things, so we can't always
# expect flight_id to be provided
if 'flight_id' in kwargs:
flight = Flight.objects.get(pk=kwargs['flight_id'])
if flight.passengers.all().count() >= flight.capacity:
# flight is full!
raise ValidationError
super(Passenger, self).clean()
class Flight(models.Model):
capacity = models.IntegerField()
passengers = models.ManyToManyField(Passenger)
请注意,为了做到这一点,您必须在验证乘客时传递航班ID:
f = Flight.objects.get(...)
p = Passenger(name='First', surname='Last')
try:
p.clean(flight_id=f.id) # full_clean calls clean, among other validations
p.save()
except ValidationError as e:
# do something to handle the error
请注意,在多线程应用程序中可以成功验证某些内容,但仍然无法在竞争条件下保存。您需要添加其他代码来处理它。
有关模型验证的详细信息,请参阅here。
答案 1 :(得分:0)
根据Django docs,您可以收听 m2m_changed 信号,该信号将触发 pre_add 和 post_add 操作。>
但是,使用具有多对多关系的add()不会调用 任何save()方法(不存在bulk参数),而是 使用QuerySet.bulk_create()创建关系。如果你需要 建立关系时执行一些自定义逻辑,听 m2m_changed信号,将触发pre_add和post_add 动作。