我想使用我在我的数据库中创建的视图作为我的django-view的源。
这可能,不使用自定义sql吗?
****** 13/02/09更新***********
与许多答案一样,您可以在数据库中创建自己的视图,然后在models.py中定义它,在API中使用它。
但是有些警告:答案 0 :(得分:93)
对于那些遇到此问题的人(来自Google或其他任何内容)的更新......
目前,Django对define model without managing database tables有一个简单的“正确方法”:
<强> Options.managed 强>
默认为
True
,这意味着Django将在syncdb
中创建相应的数据库表,并将其作为reset
管理命令的一部分删除。也就是说,Django 管理数据库表的生命周期。如果
False
,则不会对此模型执行数据库表创建或删除操作。如果模型表示通过其他方式创建的现有表或数据库视图,则此选项非常有用。managed
为False
时,这是唯一的差异。模型处理的所有其他方面与正常情况完全相同。
答案 1 :(得分:32)
自Django 1.1以来,您可以使用Options.managed。
对于旧版本,您可以轻松地为视图定义Model类,并像使用其他视图一样使用它。我刚刚使用基于Sqlite的应用程序测试它,它似乎工作正常。如果您的视图的“主键”列未命名为“id”,请确保添加主键字段,如果您的视图未被称为“app_classname”,请在Meta选项中指定视图名称。
唯一的问题是“syncdb”命令会引发异常,因为Django会尝试创建表。您可以通过在不同于models.py的单独Python文件中定义“视图模型”来防止这种情况。这样,Django在内省models.py时不会看到它们,以确定为应用程序创建的模型,因此不会尝试创建表格。
答案 2 :(得分:11)
我刚刚使用postgres 9.4和django 1.8的视图实现了一个模型。
我创建了这样的自定义迁移类:
# -*- 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规则。
答案 3 :(得分:3)
我们在使用MySQL的应用程序中广泛地完成了这项工作,以解决Django的单一数据库限制。我们的应用程序有几个数据库存在于一个MySQL实例中。只要我们为“当前”数据库中的每个表创建了视图,我们就可以通过这种方式实现跨数据库模型连接。
对于视图中的插入/更新,根据我们的用例,视图基本上是“select * from [db.table];”。换句话说,我们不做任何复杂的连接或过滤,所以插入/更新触发器从save()工作就好了。如果您的用例需要这种复杂的连接或大量过滤,我怀疑您对只读方案不会有任何问题,但可能会遇到插入/更新问题。我认为MySQL中存在一些潜在的限制因素阻止您更新到跨表的视图,具有复杂的过滤器等等。
无论如何,如果您使用的是MySQL以外的RDBMS,您的里程可能会有所不同,但Django并不关心它是否位于物理表或视图之上。 RDBMS将决定它是否实际按预期运行。正如之前的一位评论者指出的那样,你可能会把syncdb抛到窗外,虽然我们成功解决了一个post-syncdb信号,它丢弃了Django创建的物理表并运行了我们的“create view ...”命令。然而,后syncdb信号在被触发的方式上有点深奥,因此也需要注意。
编辑:当然“post-syncdb signal”我的意思是“post-syncdb listener”答案 4 :(得分:3)
从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()
希望它有所帮助; - )