我可以在 Django 中使用数据库视图作为模型吗?

问题描述 投票:0回答:5

我想使用我在数据库中创建的视图作为我的 django-view 的源。

不使用自定义sql,这可能吗?

********13/02/09 更新************

就像许多答案所建议的那样,您可以在数据库中创建自己的视图,然后通过在 models.py 中定义它来在 API 中使用它。

但有一些警告:

  • manage.pysyncdb 将不再工作
  • 视图的名称开头需要与所有其他模型(表)相同,例如,如果您的应用程序被称为“thing”,那么您的视图将需要被称为 thing_$viewname
django django-migrations sql-view django-syncdb
5个回答
95
投票

只是为那些遇到这个问题的人提供更新(来自谷歌或其他任何地方)...

目前 Django 有一个简单的“正确方法”来定义模型,无需管理数据库表

选项.托管

默认为

True

,这意味着 Django 将在 
syncdb
 中创建适当的数据库表,并作为 
reset
 管理命令的一部分删除它们。也就是说,Django 
管理数据库表的生命周期。

如果

False

,则不会对该模型进行数据库表的创建或删除操作。如果模型表示现有表或通过其他方式创建的数据库视图,这非常有用。这是当 
managedFalse
 时的
唯一
差异。模型处理的所有其他方面与正常情况完全相同。


34
投票
从 Django 1.1 开始,您可以使用

Options.driven 来实现。

对于旧版本,您可以轻松地为视图定义模型类,并像其他视图一样使用它。我刚刚使用基于 Sqlite 的应用程序对其进行了测试,它似乎工作正常。如果您的视图的“主键”列未命名为“id”,请确保添加主键字段;如果您的视图未命名为“app_classname”,请在元选项中指定视图的名称。

唯一的问题是“syncdb”命令会引发异常,因为 Django 将尝试创建表。您可以通过在与 models.py 不同的单独 Python 文件中定义“视图模型”来防止这种情况发生。这样,Django 在自省 models.py 以确定要为应用程序创建的模型时不会看到它们,因此不会尝试创建表。


14
投票
我刚刚使用 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
投票
我们在使用 MySQL 的应用程序中广泛地执行了此操作,以解决 Django 的单一数据库限制。我们的应用程序有几个数据库驻留在单个 MySQL 实例中。只要我们为“当前”数据库中的每个表创建了视图,我们就可以通过这种方式实现跨数据库模型连接。

就插入/更新视图而言,在我们的用例中,视图基本上是“select * from [db.table];”。换句话说,我们不进行任何复杂的连接或过滤,因此 save() 的插入/更新触发器工作得很好。如果您的用例需要如此复杂的联接或广泛的过滤,我怀疑您对于只读场景不会有任何问题,但可能会遇到插入/更新问题。我认为 MySQL 中存在一些潜在的约束,阻止您更新到跨表、具有复杂过滤器等的视图。

无论如何,如果您使用 MySQL 以外的 RDBMS,您的情况可能会有所不同,但 Django 并不真正关心它是否位于物理表或视图之上。 RDBMS 将决定它是否真正按照您的预期运行。正如之前的评论者指出的那样,您可能会将syncdb扔出窗外,尽管我们成功地使用 post-syncdb 信号解决了这个问题,该信号删除了 Django 创建的物理表并运行我们的“create view...”命令。然而,post-syncdb 信号的触发方式有点深奥,所以买者自负。

编辑:当然,“post-syncdb 信号”我的意思是“post-syncdb 侦听器”


3
投票

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()

希望有帮助;-)

© www.soinside.com 2019 - 2024. All rights reserved.