【问题标题】:Split Model declaration among several app in Django在 Django 中的多个应用程序之间拆分模型声明
【发布时间】:2021-11-23 22:23:57
【问题描述】:

我正在使用 Django 构建我的网站,我正面临这个逻辑问题。

我的项目是由几个应用程序制作的。

我想在每一个中声明一个更大模型的“部分”,将在一个表格中表示 - 示例:

  • 模拟人
  • 模型详情人

由于每个应用程序都指定了人的特定部分,我的想法是分散 DetailsPerson 模型的声明,以便它们出现在一个表中,但每个应用程序都扩大了应用程序需要的字段工作。

这可能吗?


  • 编辑 25/11/2021:这是我希望我的模型如何工作的图形表示

我想声明,“详细说明”表格 Person 在各种应用程序中添加应用程序本身引入的字段。通过这种方式,我可以拥有一个包含各种字段的表,并在我在项目中创建新应用程序时逐步引入。 这可能吗?我的目标是只保留一张桌子。

我尝试了 Nechoj 的第一个解决方案,但声明了 Person(models.Model),然后在另一个应用程序 PsysicalModel(Person) 添加 field_1field_2 然后 makemigrationsmigrate 不会用 field_1 和 field_2 填充我的表,而是只留下 id_person、birthdate 和城市

【问题讨论】:

    标签: python-3.x django django-models


    【解决方案1】:

    类继承

    你可以使用类继承,比如

    class Person(models.Model):
        (fields)
    
    # in other file, import this class an inherit
    class PersonWithDetails(Person):
        (add. fields)
    

    编辑:根据multitable inheritance 上的docs,这将为PersonWithDetails 创建一个包含附加字段的附加表。但是,对于用户来说,似乎所有数据都存储在一个表中。例如,filterupdate 查询按预期工作:

    PersonWithDetails.objects.filter(<some criteria>)
    

    将返回包含所有字段(来自 Person 和 PersonWithDetails)的实例,就好像所有字段都存储在单个表 PersonWithDetails 中一样。此外,可以选择所有人而不考虑他们的详细信息:

    Person.objects.all()
    

    将返回所有 Person 实例,包括那些已创建为 PersonWithDetails 的实例。如果你手头有一个 Person 实例p,那么你可以检查一个特殊属性是否存在,然后知道这个实例是否也是一个 PersonWithDetails:

    if p.personwithdetails is not None:
        p.personwithdetails.field_1
    

    这个例子展示了如果手头的实例是 Person,如何访问 PersinWithDetails 的字段。

    OneToOneField

    另一种选择是使用one-to-one 关系。

    class Person(models.Model):
        (fields)
    
    # in other file, import this class and do 
    class DetailsPerson(models.Model):
        person = models.OneToOneField(Person, on_delete=models.CASCADE)
        (additional fields)
    

    如果要向 Person 类添加详细信息,我更喜欢第二种选择。

    外键

    如果您想为一个人设置多个不同的 Detail 类,请使用 ForeignKey:

    class DetailsPerson1(models.Model):
        person = models.ForeignKey(Person, on_delete=models.CASCADE)
        (additional fields)
    
    class DetailsPerson2(models.Model):
        person = models.ForeignKey(Person, on_delete=models.CASCADE)
        (additional fields)
    

    【讨论】:

    • 我想过第二种解决方案但是这样我会有几个mysql表,每个模型一个表。相反,我的目标是从多个应用程序中获取一个多个模型,但将它们全部分组到一个 mysql 表中。我需要尝试的第一个解决方案是否创建第二个 mysql 表
    • 继承不会为基类创建多个表。 PersonWithDetails 也将是一个 Person,您可以使用 Person.objects.all() 从数据库中检索所有人员,这也将为您提供继承的对象实例。见docs.djangoproject.com/en/3.2/topics/db/models/…
    • 无法让您的第一个解决方案发挥作用(这在我看来是最佳解决方案,因为它不会创建更多表格但保持一切紧凑)。一旦在一个新文件中声明了 DetailsPerson(Person) ,我就午餐 makemigrationsmigrate 但该表不适合新字段。
    • 我编辑了我的第一篇文章,以便更好地解释我想要实现的目标
    • 为了选择最佳选项,有必要了解需要什么样的queries。 Django如何将信息存储在表中与这个问题并不真正相关,无论是一张还是两张表。在第一个选项(继承)中,Person 有一个表,PersonWith Details 有其他表,但在查询中,它看起来好像被组织在一个表中。
    猜你喜欢
    • 1970-01-01
    • 2021-10-09
    • 2011-05-07
    • 2017-02-01
    • 2017-10-31
    • 1970-01-01
    • 2016-03-07
    • 2019-10-12
    • 2017-08-25
    相关资源
    最近更新 更多