Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 在两个相关的模型中,哪一个应该包含关系的定义?_Django_Database Design_Django Models_Model_Relational Database - Fatal编程技术网

Django 在两个相关的模型中,哪一个应该包含关系的定义?

Django 在两个相关的模型中,哪一个应该包含关系的定义?,django,database-design,django-models,model,relational-database,Django,Database Design,Django Models,Model,Relational Database,首先,是的:我读过Django的,但我仍然不完全清楚如何在实践层面上实现关系,特别是关系的层次结构 一对一 我知道如何建立一对一的关系。但是,在更概念化的层面上,哪个模型应该包含对另一个模型的引用?假设我有一个公民,还有一个护照。现在,很明显,一个公民只能有一个护照,反之亦然,但是,理想情况下,公民应该包含一个引用其护照的字段,还是护照模型应该包含对其所属公民的引用 多对多 为了简单起见,假设我有一个Person模型和一个Trip模型(Trip,比如去某处旅行)。许多人可以参加一次旅行。或者换句

首先,是的:我读过Django的,但我仍然不完全清楚如何在实践层面上实现关系,特别是关系的层次结构

  • 一对一
  • 我知道如何建立一对一的关系。但是,在更概念化的层面上,哪个模型应该包含对另一个模型的引用?假设我有一个
    公民
    ,还有一个
    护照
    。现在,很明显,一个
    公民
    只能有一个
    护照
    ,反之亦然,但是,理想情况下,
    公民
    应该包含一个引用其
    护照的字段,还是
    护照
    模型应该包含对其所属
    公民的引用

  • 多对多
  • 为了简单起见,假设我有一个
    Person
    模型和一个
    Trip
    模型(
    Trip
    ,比如去某处旅行)。许多
    人可以参加一次
    旅行
    。或者换句话说:一个
    可以参加许多
    旅行
    ,而在任何一次
    旅行
    ,很多
    都可以参加。这看起来像是一种多对多关系,但是,再次强调,理想情况下,哪个模型应该包含关系的定义,带有
    行程
    字段的
    ,还是带有
    参与者
    字段的行程?为什么?这有实际意义吗


    谢谢。

    你应该具备的心智模式是父母和孩子。每种关系都有两种模式。因此,将其中一个视为父模型或主模型,将另一个视为子模型或次模型

    注意:始终将“关系”字段放在子模型中

    以下是我将如何解决您的问题:

    对于第一个,我将有一个心智模型,公民是父母,护照是孩子

    class Citizen(models.Model):
        name = models.CharField(max_length=255)
        info = models.TextField()
    
    class Passport(models.Model):
        owner = models.OneToOneField(Citizen)
        unique_no = models.CharField(max_length=30, unique=True)
    
    对于第二个问题,也要这样做。我会选择Person作为父模型,Trip作为子模型

    class Person(models.Model):
        name = models.CharField(max_length=255)
        info = models.TextField()
    
    class Trip(models.Model):
        person = models.ManyToManyField(Person)
        info = models.TextField()
    

    如果您有
    sqlitebrowser
    ,您可以使用它打开数据库并检查根据您的模型创建了哪些表。然后,你会对Django如何看待你的模型有一个更清晰的认识。

    你应该拥有的心智模型是父母和孩子。每种关系都有两种模式。因此,将其中一个视为父模型或主模型,将另一个视为子模型或次模型

    注意:始终将“关系”字段放在子模型中

    以下是我将如何解决您的问题:

    对于第一个,我将有一个心智模型,公民是父母,护照是孩子

    class Citizen(models.Model):
        name = models.CharField(max_length=255)
        info = models.TextField()
    
    class Passport(models.Model):
        owner = models.OneToOneField(Citizen)
        unique_no = models.CharField(max_length=30, unique=True)
    
    对于第二个问题,也要这样做。我会选择Person作为父模型,Trip作为子模型

    class Person(models.Model):
        name = models.CharField(max_length=255)
        info = models.TextField()
    
    class Trip(models.Model):
        person = models.ManyToManyField(Person)
        info = models.TextField()
    

    如果您有
    sqlitebrowser
    ,您可以使用它打开数据库并检查根据您的模型创建了哪些表。然后,您将更清楚地了解Django如何看待您的模型。

    这取决于您的业务逻辑。根据经验,我建议考虑一下管理应用程序。您希望如何添加新对象

    添加新对象时,您希望如何添加相关对象

    假设您有以下模型:

    Citizen(models.Model):
        name = models.CharField()
    
    Passport(models.Model):
        number = models.CharField()
        citizen = models.OneToOneField('Citizen', related_name='passport')
    
    当添加新的passport对象时,如果它还不存在,您可以添加新的公民。因为这在我看来不太符合逻辑,所以我将关系更改为:

    Citizen(models.Model):
        # other fields
        passport = models.OneToOneField('Passport', related_name='citizen')
    
    现在我们可以在admin中添加一个新的citizen对象,并在同一页面中添加相关的passport对象

    如果您使用管理应用程序,这将引导您进行更符合人体工程学的设计

    编辑:使用多对多示例展开

    m2m关系的更好例子是StackOverflow——有问题和标签。一个问题有很多标签,标签有很多问题。假设模型如下所示:

    Question(models.Model):
        title = models.CharField()
        body = models.TextField()
        author = models.CharField()
        tags = models.ManyToManyField('Tag', related_name='questions')
    
    Tag(models.Model):
        name = models.CharField()
    
    我们为什么要质疑这种关系?这应该是非常合乎逻辑的-当创建一个新问题时,您希望为它设置标签。创建新标记时,您不关心与它相关的任何问题。您可以创建标记,稍后在创建问题时,将其与标记关联。
    如果标签还不存在,您可以在添加新问题时从管理员处添加标签


    我希望第二个例子更明显。

    这取决于您的业务逻辑。根据经验,我建议考虑一下管理应用程序。您希望如何添加新对象

    添加新对象时,您希望如何添加相关对象

    假设您有以下模型:

    Citizen(models.Model):
        name = models.CharField()
    
    Passport(models.Model):
        number = models.CharField()
        citizen = models.OneToOneField('Citizen', related_name='passport')
    
    当添加新的passport对象时,如果它还不存在,您可以添加新的公民。因为这在我看来不太符合逻辑,所以我将关系更改为:

    Citizen(models.Model):
        # other fields
        passport = models.OneToOneField('Passport', related_name='citizen')
    
    现在我们可以在admin中添加一个新的citizen对象,并在同一页面中添加相关的passport对象

    如果您使用管理应用程序,这将引导您进行更符合人体工程学的设计

    编辑:使用多对多示例展开

    m2m关系的更好例子是StackOverflow——有问题和标签。一个问题有很多标签,标签有很多问题。假设模型如下所示:

    Question(models.Model):
        title = models.CharField()
        body = models.TextField()
        author = models.CharField()
        tags = models.ManyToManyField('Tag', related_name='questions')
    
    Tag(models.Model):
        name = models.CharField()
    
    我们为什么要质疑这种关系?这应该是非常合乎逻辑的-当创建一个新问题时,您希望为它设置标签。创建新标记时,您不关心与它相关的任何问题。您可以创建标记,稍后在创建问题时,将其与标记关联。
    如果标签还不存在,您可以在添加新问题时从管理员处添加标签


    我希望第二个例子更明显。

    这背后的理论被称为“最佳实践阶梯”,如果您想了解更多有关数据结构的信息,您应该查阅该阶梯

    第三种形式告诉我们: