我如何限制或选择一个或另一个外键?

问题是概念性的(数据库关系),因此语言不是这里的重点,但我正在使用 Python 和 Django。

我有 3 个模型/桌子:

  • 公司

  • 顾客

  • 地址

例如。

class Company(models.Model):

    name = models.CharField(max_lenght=100) #example


class Customer(models.Model):

    name = models.CharField(max_lenght=100) #example


class Adress(models.Model):

    country = models.CharField(max_lenght=100) #example

    state = models.CharField(max_lenght=100) #example

    

    # here I want the address owner

    # I could put something like this:

    company = models.ForeignKey(Company, on_delete=models.PROTECT)

    customer = models.ForeignKey(Customer, on_delete=models.PROTECT)

我希望该地址属于客户或公司,但不能同时属于两者。

我知道我可以简单地创建 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)

但我不想这么做,原因有两个:

  1. 重复的代码以及在 Django 管理面板中我将有两个单独的地址列表的事实,这没有多大意义,因为所有地址在结构上都是相同的。我可以修复创建基类、继承基类等的重复代码,但我在管理面板中仍然会有 2 个列表。

  2. 将来我可能会遇到同样的概念性问题,但会更加复杂,例如,某些事物有 300 个类,而 1 个类应该只有 300 个类中的一个具有外键。

我应该怎么办?


qq_花开花谢_0
浏览 108回答 2
2回答

牧羊人nacy

您可以尝试将外键设置为 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)

千万里不及你

下面是一个DB模型。-- Address ADR exists. -- address {ADR}      PK {ADR}Party是个人或组织的通用术语;判别器TYP用于区分两者。-- Party PTY, of party-type TYP, resides at address ADR. -- party {PTY, TYP, ADR}    PK {PTY}    SK {PTY, TYP} CHECK TYP in {'P', 'O'} FK {ADR} REFERENCES address {ADR}-- Person, a party PTY of party-type TYP = 'P', exists. -- person {PTY, TYP}     PK {PTY} CHECK TYP = 'P' FK {PTY, TYP} REFERENCES party {PTY, TYP}-- Organization, a party PTY of party-type TYP = 'O', exists. -- organization {PTY, TYP}           PK {PTY} CHECK TYP = 'O' FK {PTY, TYP} REFERENCES party {PTY, TYP}笔记:All attributes (columns) NOT NULL PK = Primary Key AK = Alternate Key   (Unique) SK = Proper Superkey (Unique) FK = Foreign Key关于亚型的一句话。实现子类型约束的正确方法是使用断言(CREATE ASSERTION),但它在主要数据库中仍然不可用。我正在使用FKs它,并且与所有其他替代方法一样,它并不完美。人们争论很多,关于SO和SE-DBA,哪个更好。我鼓励您也检查其他方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python