(這是一個老問題,但仍然絆倒人了,仍然是高度相關的,以使用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只是有一天。