Django 如何约束或选择一个或其他外键?
问题是概念性的(数据库关系),所以这里不关注语言,但我使用的是Python和Django 我有3个模型/表格:Django 如何约束或选择一个或其他外键?,django,database,database-design,foreign-keys,Django,Database,Database Design,Foreign Keys,问题是概念性的(数据库关系),所以这里不关注语言,但我使用的是Python和Django 我有3个模型/表格: 公司 顾客 地址 例如 我希望地址属于客户或公司,但不能同时属于两者。 我知道我可以简单地创建2个地址类,例如CustomerAddress、CompanyAddress,每个类都有正确的外键: class Company(models.Model): name = models.CharField(max_lenght=100) #example class Custo
- 公司
- 顾客
- 地址
我知道我可以简单地创建2个地址类,例如CustomerAddress、CompanyAddress,每个类都有正确的外键:
class Company(models.Model):
name = models.CharField(max_lenght=100) #example
class Customer(models.Model):
name = models.CharField(max_lenght=100) #example
class CompanyAdress(models.Model):
country = models.CharField(max_lenght=100) #example
state = models.CharField(max_lenght=100) #example
company = models.ForeignKey(Company, on_delete=models.PROTECT)
class CustomerAdress(models.Model):
country = models.CharField(max_lenght=100) #example
state = models.CharField(max_lenght=100) #example
customer = models.ForeignKey(Company, on_delete=models.PROTECT)
但我不想这么做有两个原因:
PS:我不会说英语,如果我犯了一些英语错误,非常抱歉。您可以尝试将外键设置为null=True,并根据需要通过视图控制数据库中的输入:
class Address(models.Model):
country = models.CharField(max_lenght=100)
state = models.CharField(max_lenght=100)
company = models.ForeignKey(Company, on_delete=models.PROTECT, null=True)
customer = models.ForeignKey(Customer, on_delete=models.PROTECT, null=True)
您可以尝试将外键设置为null=True,并根据需要通过视图控制数据库中的输入:
class Address(models.Model):
country = models.CharField(max_lenght=100)
state = models.CharField(max_lenght=100)
company = models.ForeignKey(Company, on_delete=models.PROTECT, null=True)
customer = models.ForeignKey(Customer, on_delete=models.PROTECT, null=True)
有关UML图,请查看Martin Fowler的。下面是一个DB模型
——地址ADR存在。
--
地址{ADR}
PK{ADR}
一方
是个人或组织的通用术语;鉴别器TYP
用于区分两者
——参与方类型的参与方PTY位于ADR地址。
--
当事人{PTY,TYP,ADR}
PK{PTY}
SK{PTY,TYP}
检查{P',O'}中的类型
FK{ADR}引用地址{ADR}
--个人,存在类型为“P”的参与方PTY。
--
人{PTY,TYP}
PK{PTY}
检查类型='P'
FK{PTY,TYP}引用方{PTY,TYP}
--组织,存在类型为“O”的参与方PTY。
--
组织{PTY,TYP}
PK{PTY}
检查类型='O'
FK{PTY,TYP}引用方{PTY,TYP}
注:
所有属性(列)不为空
PK=主键
AK=备用键(唯一)
SK=正确的超级键(唯一)
FK=外键
关于子类型的一句话。实现子类型约束的正确方法是使用断言(
createassertion
),但它在主要数据库中仍然不可用。我使用的是FKs
,与所有其他替代方法一样,它并不完美。关于SO和SE-DBA,人们争论了很多,什么更好。我鼓励您也检查其他方法。有关UML图,请查看Martin Fowler的。下面是一个DB模型
——地址ADR存在。
--
地址{ADR}
PK{ADR}
一方
是个人或组织的通用术语;鉴别器TYP
用于区分两者
——参与方类型的参与方PTY位于ADR地址。
--
当事人{PTY,TYP,ADR}
PK{PTY}
SK{PTY,TYP}
检查{P',O'}中的类型
FK{ADR}引用地址{ADR}
--个人,存在类型为“P”的参与方PTY。
--
人{PTY,TYP}
PK{PTY}
检查类型='P'
FK{PTY,TYP}引用方{PTY,TYP}
--组织,存在类型为“O”的参与方PTY。
--
组织{PTY,TYP}
PK{PTY}
检查类型='O'
FK{PTY,TYP}引用方{PTY,TYP}
注:
所有属性(列)不为空
PK=主键
AK=备用键(唯一)
SK=正确的超级键(唯一)
FK=外键
关于子类型的一句话。实现子类型约束的正确方法是使用断言(
createassertion
),但它在主要数据库中仍然不可用。我使用的是FKs
,与所有其他替代方法一样,它并不完美。关于SO和SE-DBA,人们争论了很多,什么更好。我建议您也检查其他方法。为什么不在公司和客户型号中添加外键地址字段?搜索派对型号。共同模式。或者超级类型、子类型为什么不在公司和客户型号中添加外键地址
字段?搜索派对型号
。共同模式。或者超级类型,子类型我认为正确的答案我认为正确的答案