如何在Django中建模“一个或多个”关系?

时间:2014-11-19 23:09:25

标签: python django database-design django-models

我有一个模型OwnerOwner的类型可以是IndividualBusiness。根据类型,Owner可能与Property模型具有一对一或一对多的关系。如果Individual,它只能有一个Property,但如果Business,则可能有Property个。你如何在Django中建模?如何强制Individual只有一个Property

2 个答案:

答案 0 :(得分:3)

如果您正在使用PostgreSQL或SQLite,则可以使用部分唯一索引强制执行此操作。从Django 2.2开始,您可以执行此操作declaratively,例如:

from django.db.models import Model, Q, UniqueConstraint

class Property(Model):
    ...
    class Meta:
        constraints = [UniqueConstraint(fields=["owner"], condition=Q(type="Individual"))]

在Django 2.2之前,您可以通过迁移完成此操作。类似的东西:

class Migration(migrations.Migration):

    dependencies = [ ... ]

    operations = [
        migrations.RunSQL("CREATE UNIQUE INDEX property_owner 
                           ON property(owner_id) 
                           WHERE type = 'Individual'"),
    ]

答案 1 :(得分:2)

我建议使用ForeignKey为Owner创建Property模型,然后通过覆盖类的save函数来添加一些自定义验证。

from django.db import IntegrityError

class Property(models.Model):
    owner = models.ForeignKey(Owner)

    def save(self, *args, **kwargs):
        if self.owner.type == "Individual":
            if Property.objects.filter(owner=self.owner).exists():
                raise IntegrityError
        super(Property, self).save(*args, **kwargs)

这不会涵盖所有情况,例如手动将记录添加到数据库或使用绕过保存功能的某些django方法,但它将涵盖大多数情况。