【问题标题】:Combine the information of two tables into a single Django model将两个表的信息组合成一个 Django 模型
【发布时间】:2016-03-23 13:20:40
【问题描述】:

我需要使用以下两个表读取外部数据库的数据(我无法修改表结构):

表1

  • 键(主键)
  • 字段1

表2

  • 键(主键)
  • 字段2

是否可以将这两个表组合成一个 Django 模型,如下所示:

型号:

  • 键(主键)
  • 字段1
  • 字段2

附加信息:

Table2 中条目的键是 Table1 中条目的子集。所以对于表 2 中的任何条目,表 1 中都有匹配的条目,反之则不然

到目前为止的工作:

我对每个表(1 和 2)都有一个模型,而 Table1 模型有一个“field2”@property,用于查找 Table2 模型中的相应信息。

另外,我可以使用以下查询在 sql 级别执行此操作:

SELECT
  table1.key,
  table1.field1,
  table2.field2,
FROM
  table1
    LEFT OUTER JOIN table2
      ON table1.key=table2.key
ORDER BY table1.key ASC

=== 看到部分答案后解决方案实施细节更新:

来自Daniel Roseman's answer

我最终得到了两个模型:

class Model1(models.Model):
    key = models.CharField(max_length=100, primary_key=True)
    field1 = models.TextField()

    class Meta:
        managed = False
        db_table = 'Table1'

    def field2_value(self):
        try:
            return self.field2.value
        except Model2.DoesNotExist:
            return None


class Model2(models.Model):
    key = models.OneToOneField(Model1, primary_key=True, db_column='key',
                               related_name='field2')
    field2 = models.TextField()

    class Meta:
        managed = False
        db_table = 'Table2'

虽然这与我问这个问题时最初的想法不完全一样,但它符合我想要的用例

另外,这里是相应的管理类:

class Model2Admin(admin.StackedInline):
    model = Model2


@admin.register(Model1)
class Model1Admin(admin.ModelAdmin):
    inlines = (Model2Admin,)
    list_display = ('key', 'field1', 'field2_value')
    # Loads the related property in one SQL call instead of one call per entry
    list_select_related = ('field2',)

谢谢KaaN SARIKAYA for your great answer。我不知道我可以创建两个表的视图。如果我可以修改数据库结构,我会选择您的选项。

【问题讨论】:

标签: django django-models


【解决方案1】:

更好的解决方案是将它们保留为两个模型,但第二个的主键是第一个的 OneToOneField。

【讨论】:

    【解决方案2】:

    您无法合并模型,因为它们是 2 个物理表,django 模型由数据库表名绑定,因此您无法做您想做的事情。如果您对这些外部数据库表有控制权并有权修改它们,则应先修改架构并合并数据。如果你不想或者你不能修改任何东西,你现在的方式是可以的。

    【讨论】:

      【解决方案3】:

      您可以在 sql 上创建一个 table_view 并在 django 上创建一个抽象模型。假设您有 2 个物理模型和表格。

      SQL 代码:

      CREATE OR REPLACE VIEW combine_two_model_view AS 
      SELECT
      mt1.name as mt1_name,
      mt2.name as mt2_name,
      mt1.pub_date as mt1_pub_date
      .
      .
      .
      .
      
      FROM modeltable1 mt1
      
       LEFT JOIN modeltable2 mt2 ON mt2.id = mt1.id
      
      
      ALTER TABLE combine_two_model_view
      OWNER TO dbuser;
      

      我们创建了 sql 视图表。现在,我们将创建一个抽象模型

      在你的 models.py 中:

      class YourModelsCombine(models.Model):
          class Meta:
              abstract = True
              db_table = "combine_two_model_view"
      
          mt1_name = models.CharField(max_length=100)
          mt2_name = models.TextField(max_length=2000)
          mt1_pub_date = models.DateTimeField("Publish Date", auto_now_add=True)
          mt2_pub_date = models.DateField("Updated Date", auto_now=True)
          mt1_integer = models.IntegerField(default=0)
          #etc
      

      注意:请确保您的表视图变量名称和模型变量名称必须相同。最后; 在你的 admin.py 中:

      admin.site.register(YourModelsCombine)
      

      您将在 django-admin 上看到两个表的组合 希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-26
        • 1970-01-01
        • 2014-03-28
        • 2015-09-28
        • 2017-08-26
        • 1970-01-01
        • 2021-03-05
        相关资源
        最近更新 更多