根据Django中有多少外键引用该模型限制外键数量?

时间:2015-08-06 03:06:42

标签: python django django-models

我是Django的新手,所以如果这是一个愚蠢的问题,请原谅我!

所以我有一个名为Resident的模型,它定义了一个租户的一些基本特征,这些特征将出租房间:

class Resident(models.Model):
    fname = models.CharField(max_length=50)
    lname = models.CharField(max_length=50)
    email = models.EmailField()
    room = models.ForeignKey('Room')

我还有一个名为Room的模型,它定义了租户租用的房间的基本特征:

class Room(models.Model):
    number = models.IntegerField()
    floor = models.IntegerField()
    beds = models.IntegerField()

如何根据Room.beds定义的房间床位数,对Resident.room字段中的外键数量进行限制?例如,如果Room.beds == 2,我如何限制Resident允许的外键数量最多为2?

2 个答案:

答案 0 :(得分:1)

使用pre_save信号,每当您尝试创建新的Resident实例时,您都可以先检查居住者所在房间内可用床的总数:

from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.core.exceptions import ValidationError

@receiver(pre_save, sender=Resident)
def resident_pre_save(sender, instance, **kwargs):
    if instance.room.beds == instance.room.resident_set.count():
        raise ValidationError('No bed left for: {}'.format(instance)    

您可以在models.py的末尾添加上述代码。有关信号如何在Django中工作的更多信息,请参阅documentation

您可以使用.save()包装try/except:方法,以便在您可能希望将其传输到记录器时优雅地处理验证错误。

def save(self, *args, **kwargs):    
    try:
      super(Resident, self).save(*args, **kwargs)
    except ValidationError, exc:
        logger.error('Saving resident failed. Error: {}'.format(exc))

答案 1 :(得分:1)

我喜欢使用验证器的方式:

40097.586458333 - Number of days that have passed since 12/30/1899.

使用验证器将使Django正确处理它,例如,在管理面板中显示错误。