2009-02-03 103 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规则。

相关问题