我想使用我在数据库中创建的视图作为我的 django-view 的源。
不使用自定义sql,这可能吗?
********13/02/09 更新************
就像许多答案所建议的那样,您可以在数据库中创建自己的视图,然后通过在 models.py 中定义它来在 API 中使用它。
但有一些警告:
只是为那些遇到这个问题的人提供更新(来自谷歌或其他任何地方)...
目前 Django 有一个简单的“正确方法”来定义模型,无需管理数据库表:
选项.托管
默认为
True
,这意味着 Django 将在syncdb
中创建适当的数据库表,并作为reset
管理命令的一部分删除它们。也就是说,Django管理数据库表的生命周期。 如果
False
,则不会对该模型进行数据库表的创建或删除操作。如果模型表示现有表或通过其他方式创建的数据库视图,这非常有用。这是当managed
为False
时的唯一差异。模型处理的所有其他方面与正常情况完全相同。
Options.driven 来实现。
对于旧版本,您可以轻松地为视图定义模型类,并像其他视图一样使用它。我刚刚使用基于 Sqlite 的应用程序对其进行了测试,它似乎工作正常。如果您的视图的“主键”列未命名为“id”,请确保添加主键字段;如果您的视图未命名为“app_classname”,请在元选项中指定视图的名称。唯一的问题是“syncdb”命令会引发异常,因为 Django 将尝试创建表。您可以通过在与 models.py 不同的单独 Python 文件中定义“视图模型”来防止这种情况发生。这样,Django 在自省 models.py 以确定要为应用程序创建的模型时不会看到它们,因此不会尝试创建表。
我创建了这样的自定义迁移类:
# -*- 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 规则。
就插入/更新视图而言,在我们的用例中,视图基本上是“select * from [db.table];”。换句话说,我们不进行任何复杂的连接或过滤,因此 save() 的插入/更新触发器工作得很好。如果您的用例需要如此复杂的联接或广泛的过滤,我怀疑您对于只读场景不会有任何问题,但可能会遇到插入/更新问题。我认为 MySQL 中存在一些潜在的约束,阻止您更新到跨表、具有复杂过滤器等的视图。
无论如何,如果您使用 MySQL 以外的 RDBMS,您的情况可能会有所不同,但 Django 并不真正关心它是否位于物理表或视图之上。 RDBMS 将决定它是否真正按照您的预期运行。正如之前的评论者指出的那样,您可能会将syncdb扔出窗外,尽管我们成功地使用 post-syncdb 信号解决了这个问题,该信号删除了 Django 创建的物理表并运行我们的“create view...”命令。然而,post-syncdb 信号的触发方式有点深奥,所以买者自负。
编辑:当然,“post-syncdb 信号”我的意思是“post-syncdb 侦听器”
Django官方文档,你可以这样调用视图:
#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()
希望有帮助;-)