在Django模型中何时使用一对一关系

2024-09-24 00:36:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我读过a fewplaces(见第二个答案),Django模型中的一对一关系几乎总是只用于继承或访问其他不可访问的模型(如Django用户模型)。

但是,在某些情况下,如果有一个对象总是正好有另一个对象的一个实例,那么您在逻辑上希望将这两个对象分开。比如说,你的应用程序正在存储有关汽车的信息。每辆车只有一个司机,每个司机只开一辆车。把汽车和司机分成两个不同的型号有什么不合理吗?


Tags: 对象django实例答案用户模型信息应用程序
2条回答

django文档给出了一个great answer

For example, if you were building a database of “places”, you would build pretty standard stuff such as address, phone number, etc. in the database. Then, if you wanted to build a database of restaurants on top of the places, instead of repeating yourself and replicating those fields in the Restaurant model, you could make Restaurant have a OneToOneField to Place (because a restaurant “is a” place; in fact, to handle this you’d typically use inherit Each car has exactly one driver and each driver only drives one car. Does it not make sense to separate car anance, which involves an implicit one-to-one relation).

Django使用OneToOne对继承进行建模(可能在内部使用它,但我还没有签出源代码)。我觉得如果django提供了一个工具,你可以用一种你可以保护的方式来使用它,为什么不使用它呢?如果一辆车只有一个司机,那么在数据库中使用django提供的工具(OneToOneField)来实现这一点似乎是有道理的

假设您有一家公司,并使intranet工具列出所有员工、他们的职位、办公室、部门、薪水等。您将在Django models.py中创建一个类员工,可能如下所示:

class Employee(models.Model):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    position = models.CharField(max_length=255)
    office = models.CharField(max_length=20)
    salary = models.IntegerField()
    department = models.ForeignKey(Department, related_name='employees')

但由于某些原因,您不希望所有员工都可以访问薪资,可能在管理区域中有许多具有redactor身份的人,决定将其外包给自己的模型并更改模型员工:

class Employee(models.Model):
    # above attributes
    salary = models.OneToOneField(Salary)

当然还有其他方法隐藏这些信息,但有一种可能是将这些信息分成两个表,即使它们只是简单的1:1关系。

你的公司是一家软件公司,你介绍配对编程。每个员工都有一个配对编程伙伴。它可以只是一个编程伙伴。所以你要重新调整你的模式:

class Employee(models.Model):
    # above attributes
    pair_programmer = models.OneToOneField('self')

这将是一个递归的一对一关系。

一对一的关系并不常见,在初学者的教程中很难找到,但是如果有一些特定的要求,您会发现自己创建了1:1的关系来解决问题。

这是我工作中的一个真实的例子。我是生物信息学家,为微生物制作软件。它们按属和种分类。每个属可以包含一个或多个种,但一个种只能属于一个属。这是一个明确的1:n关系。但现在,一个属有一个模式种,只有一个而且只有一个。模式种可以属于一个属。我把models.OneToOneField放在这里,除了models.ForeignKey

事先不要太担心1:1的关系。当你遇到一些具体的问题时,你会发现你是否需要1:1的关系。

相关问题 更多 >