2009-02-03 82 views
55

我想使用我在我的數據庫中創建的視圖作爲我的django視圖的源代碼。我可以在Django中使用數據庫視圖作爲模型嗎?

這是可能的,而不使用自定義的SQL?

****** 13/02/09 UPDATE ***********

像許多答案的建議,你可以使自己的觀點在數據庫中,然後通過在models.py中定義它在API中使用它。

一定的警示作用,但:

  • manage.py執行syncdb不會工作了
  • 認爲需要在它的名字開始與所有其他機型(表)同樣的事情,例如,如果你的應用程序是所謂的「東西」,那麼你的觀點將需要被稱爲thing_ $ viewname
+0

要使syncdb命令起作用,請勿將模型類放入models.py中的視圖,而應將其放入單獨的文件! – 2009-02-15 15:39:55

+2

更好:請在模型的Meta類中查看以下關於managed = False的答案。 – 2010-01-20 09:17:45

+3

視圖不需要與應用程序具有相同的名稱。只需使用元字段db_table。例如名爲its_a_View的視圖。 class Meta:db_table = u'its_a_view' – grantk 2011-09-09 02:30:40

回答

33

由於Django 1.1,您可以使用Options.managed

對於舊版本,您可以輕鬆地爲視圖定義Model類並像使用其他視圖一樣使用它。我只是使用基於Sqlite的應用程序來測試它,它似乎工作正常。只要確保在視圖的「主鍵」列未命名爲「id」的情況下添加主鍵字段並在Meta選項中指定了視圖的名稱(如果您的視圖未被稱爲「app_classname」)。

唯一的問題是,「syncdb」命令會引發異常,因爲Django會嘗試創建表。您可以通過在不同於models.py的單獨Python文件中定義「視圖模型」來防止這種情況。這樣,當反省models.py以確定爲應用程序創建的模型並且因此不會嘗試創建表時,Django不會看到它們。

+0

任何想法如何處理調用它的保存方法?一些dbms具有可更新的視圖。 – 2009-02-04 23:28:34

3

我們在我們的應用程序中用MySQL解決Django的單一數據庫限制時做了相當廣泛的工作。我們的應用程序有幾個數據庫生活在一個MySQL實例中。只要我們爲「當前」數據庫中的每個表創建了視圖,就可以通過這種方式實現跨數據庫模型連接。就插入/更新視圖而言,在我們的用例中,視圖基本上是「select * from [db.table];」。換句話說,我們不做任何複雜的連接或過濾,所以從save()中插入/更新觸發器工作得很好。如果您的用例需要如此複雜的連接或廣泛的過濾,我懷疑您對於只讀場景不會有任何問題,但可能會遇到插入/更新問題。我認爲在MySQL中有一些潛在的限制可以防止你更新到跨越表格的視圖,具有複雜的過濾器等。

無論如何,如果你使用的不是MySQL的RDBMS,你的里程可能會有所不同,但Django不會'如果它坐在物理桌子或視圖的頂部,它真的很在乎。這將是RDBMS決定它是否實際按照您的預期運行。正如前面的評論者指出的那樣,儘管我們成功地使用了後syncdb信號來放棄由Django創建的物理表並運行我們的「創建視圖...」命令,但您可能會將syncdb扔出窗口。然而,後syncdb信號在它被觸發的方式上有點神祕,所以在那裏也要警惕。

編輯:當然是「執行syncdb後的信號」我的意思是「執行syncdb後監聽」

90

只是一個更新對於那些誰就會碰到這個問題(來自谷歌或其他任何)...

目前的Django有一個簡單的 「正確的方式」 define model without managing database tables

Options.managed

默認爲True,這意味着Django會在syncdb創建相應的數據庫表和其取走一部分管理命令的一個reset。也就是說,Django 管理着數據庫表的生命週期。

如果是False,則不會爲該模型執行數據庫表創建或刪除操作。如果模型表示已經通過其他方式創建的現有表或數據庫視圖,這很有用。這是只有區別時managedFalse。模型處理的所有其他方面與正常情況完全相同。

2

Django Official Documentation,你可以這樣調用視圖:

#import library 
from django.db import connection 

#Create the cursor 
cursor = connection.cursor() 

#Write the SQL code 
sql_string = 'SELECT * FROM myview' 

#Execute the SQL 
cursor.execute(sql_string) 
result = cursor.fetchall() 

希望它可以幫助;-)

9

我只是用在Postgres 9.4和1.8的Django視圖實現模型。

我創建的自定義遷移類是這樣的:

# -*- coding: utf-8 -*- 
from __future__ import unicode_literals 

from django.db import migrations 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('myapp', '0002_previousdependency'), 
    ] 

    sql = """ 
    create VIEW myapp_myview as 
    select your view here 
    """ 

    operations = [ 
     migrations.RunSQL("drop view if exists myapp_myview;"), 
     migrations.RunSQL(sql) 
    ] 

我寫的模型,我通常會。它適用於我的目的。

注意 - 當我跑makemigrations新的遷移文件的模型,我手動刪除創建的。

完全披露 - 我的視圖是隻讀的,因爲我使用的是從jsonb數據類型派生的視圖,並且沒有寫入ON UPDATE INSTEAD規則。

相關問題