2

这是视图表的模型。

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

4 回答 4

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 类选项的文档在此处。相关报价:

如果为 False,则不会对该模型执行任何数据库表创建或删除操作。如果模型表示现有表或已通过其他方式创建的数据库视图,这将很有用。这是 managed 为 False 时的唯一区别。模型处理的所有其他方面与正常情况完全相同。

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

qry_desc_char_list = QryDescChar.objects.all()

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

于 2009-11-20T14:40:52.490 回答
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 实际上意味着“什么都不做”——否则它仍会尝试(不必要地)在执行删除周期之前查询并收集所有相关对象,并且查询将失败,停止整个操作。

顺便说一句,就在前几天,我写了一篇关于如何做到这一点的深入解释

于 2012-08-15T17:08:19.890 回答
0

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

于 2009-11-03T18:23:54.633 回答
-1

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

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

于 2009-11-02T23:46:56.573 回答