将两个表的信息组合到一个Django模型中

时间:2016-03-23 13:20:41

标签: django django-models

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

表1

  • 键(主键)
  • 字段1

表2

  • 键(主键)
  • 字段2

是否可以将这两个表组合成一个看似如下的Django模型:

型号:

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

其他信息:

Table2中条目的键是Table1中条目的子集。因此,对于Table2中的任何条目,Table1中都有匹配的条目,但不是反之亦然

到目前为止工作:

每个表(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。我不知道我可以创建两个表的视图。如果我可以修改数据库结构,我会选择你的选择。

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

你不能合并模型,因为它们是2个物理表,django模型被数据库表名绑定,所以你不能做你想做的事。如果您拥有对这些外部数据库表的控制权并且有权修改它们,则应首先修改模式并合并数据。如果您不想要,或者您无法修改任何内容,那么您当前的方式就可以了。

答案 2 :(得分:1)

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

SQL CODE:

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上看到两个表的组合 我希望这对你有帮助