2009-11-02 59 views
2

这是视点表的典范。我如何获得对象的列表从PostgreSQL视图表显示

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' 

这是我用它来创建表

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; 

我不知道如果我需要在模型或意见或两者功能的SQL。我想要从该数据库中获取对象列表来显示它。这可能是容易的,但让我有一些问题

回答

-1

你正试图从一个视图提取记录在Django的即时通讯新的蟒蛇。这是不正确的,因为视图不映射到模型,表格映射到模型。

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

0

如果您的RDBMS允许您创建可写的意见,并在创建视图具有比表Django的确切结构会造成我想这应该直接工作。

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 

的文档管理型元级选项here。一个相关报价:

如果假,没有数据库表的创建 或删除操作将成为这一模式进行 。这是 有用的,如果该模型代表一个 现有表或该 已经通过一些其他方式创建的数据库视图。 这是 管理的唯一区别是False。 模型处理的所有其他方面与 正常相同。

一旦完成,您应该能够正常使用您的模型。要获得对象的列表你会做这样的事情:

qry_desc_char_list = QryDescChar.objects.all() 

实际得到的名单到您的模板你可能想看看通用的意见,特别是对object_list视图。

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只是有一天。