2009-11-02 53 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只是有一天。