如何从postgresql视图表中获取要显示的对象列表

时间:2009-11-02 22:46:14

标签: django postgresql django-models django-views

这是视图表的模型。

class QryDescChar(models.Model): 
 iid_id = models.IntegerField()
 cid_id = models.IntegerField()
 cs = models.CharField(max_length=10)
 cid = models.IntegerField()
 charname = models.CharField(max_length=50)
 class Meta:
     db_table = u'qry_desc_char'

这是我用来创建表的SQL

CREATE VIEW qry_desc_char as
 SELECT  
    tbl_desc.iid_id,
    tbl_desc.cid_id,
    tbl_desc.cs,
    tbl_char.cid,
    tbl_char.charname
FROM tbl_desC,tbl_char 
WHERE tbl_desc.cid_id = tbl_char.cid;

我不知道我是否需要模型或视图中的功能或两者兼而有之。我想从该数据库中获取一个对象列表来显示它。这可能很简单,但是在Django和python中我很新,所以我有一些问题

4 个答案:

答案 0 :(得分:6)

Django 1.1带来了一个你可能觉得有用的新功能。您应该可以执行以下操作:

 class QryDescChar(models.Model): 
     iid_id = models.IntegerField()
     cid_id = models.IntegerField()
     cs = models.CharField(max_length=10)
     cid = models.IntegerField()
     charname = models.CharField(max_length=50)
 class Meta:
     db_table = u'qry_desc_char'
     managed = False

托管Meta类选项的文档是here。相关引用:

  

如果为False,则不创建数据库表   或删除操作   为这个模型执行。这是   如果模型代表一个有用的话   现有表格或数据库视图   已经通过其他方式创建。   这是唯一的区别   托管是假的。所有其他方面   模型处理完全相同   正常。

完成后,您应该能够正常使用您的模型。要获取对象列表,您需要执行以下操作:

qry_desc_char_list = QryDescChar.objects.all()

要实际将列表放入模板,您可能需要查看通用视图,特别是object_list视图。

答案 1 :(得分:0)

如果您的RDBMS允许您创建可写视图,并且您创建的视图具有与Django将创建的表格相同的结构,我想这应该直接起作用。

答案 2 :(得分:0)

(这是一个古老的问题,但这个区域仍然会引起人们的兴趣,并且仍然与任何使用Django且具有预先存在的规范化架构的人高度相关。)

在SELECT语句中,您需要添加一个数字“id”,因为Django期望一个,即使在非托管模型上也是如此。你可以使用row_number()窗口函数来完成这个,如果某个行上没有保证唯一的整数值(并且通常就是这种情况)。

在这种情况下,我正在使用带窗口函数的ORDER BY子句,但是你可以做任何有效的事情,而当你在它时,你也可以使用一个对你有用的子句。只是确保你不要尝试使用Django ORM点引用关系,因为它们默认情况下会查找“id”列,而你的是假的。

此外,如果您要在对象中使用它,我会考虑将输出列重命名为更有意义的内容。有了这些更改,查询看起来会更像(当然,用自己的术语替换“AS”子句):

CREATE VIEW qry_desc_char as
 SELECT
    row_number() OVER (ORDER BY tbl_char.cid) AS id,
    tbl_desc.iid_id AS iid_id,
    tbl_desc.cid_id AS cid_id,
    tbl_desc.cs AS a_better_name,
    tbl_char.cid AS something_descriptive,
    tbl_char.charname AS name
FROM tbl_desc,tbl_char 
WHERE tbl_desc.cid_id = tbl_char.cid;

完成后,在Django中,您的模型可能如下所示:

class QryDescChar(models.Model):
    iid_id = models.ForeignKey('WhateverIidIs', related_name='+',
                                db_column='iid_id', on_delete=models.DO_NOTHING)
    cid_id = models.ForeignKey('WhateverCidIs', related_name='+',
                                db_column='cid_id', on_delete=models.DO_NOTHING)
    a_better_name = models.CharField(max_length=10)
    something_descriptive = models.IntegerField()
    name = models.CharField(max_length=50)

    class Meta:
        managed = False
        db_table = 'qry_desc_char'

你不需要id列名称末尾的“_id”部分,因为你可以使用“db_column”参数在Django模型上声明一些更具描述性的列名,就像我上面所做的那样(但是这里我只是为了防止Django将另一个“_ id”添加到cid_id和iid_id的末尾 - 这为你的代码添加了零语义值)。另外,请注意“on_delete”参数。 Django在级联删除方面做了自己的事情,在一个有趣的数据模型上你不想要这个 - 当涉及到视图时,你只会得到一个错误和一个中止的事务。在Django 1.5之前你必须修补它以使DO_NOTHING实际上意味着“什么都不做” - 否则它仍会尝试(不必要地)查询并收集所有相关对象,然后再进行删除循环,查询将失败,停止整个行动。

顺便说一下,I wrote an in-depth explanation of how to do this 只是前几天。

答案 3 :(得分:-1)

您正尝试从视图中提取记录。这是不正确的,因为视图不映射到模型,表映射到模型。

您应该使用Django ORM来获取QryDescChar个对象。请注意,Django ORM将直接从表中获取它们。您可以参考Django文档获取extra()select_related()方法,这些方法将允许您以不同方式获取相关数据(您希望从其他表中获取的数据)。