gpt4 book ai didi

Django:如何将原始 sql 查询的结果映射到管理 ListView 中的模型实例?

转载 作者:行者123 更新时间:2023-12-01 05:36:03 26 4
gpt4 key购买 nike

考虑简单模型:

class Item(models.Model):
name = models.CharField(...)
unit_cost = models.DecimalField(...)
unit_price = models.DecimalField(...)

它具有以下管理类:
class ItemAdmin(admin.ModelAdmin):
def queryset(self, request):
qs = self.model._default_manager.get_query_set()
qs2 = self.model._default_manager.raw('''
SELECT
"stock_item"."id",
"stock_item"."name",
"stock_item"."unit_cost",
"stock_item"."unit_price"
FROM
"stock_item"
''')
qs3 = RawQuerySet('''
SELECT
"stock_item"."id",
"stock_item"."name",
"stock_item"."unit_cost",
"stock_item"."unit_price"
FROM
"stock_item"
''', self.model)
return qs # WORKS
return qs2 # DOESN'T WORK
return qs3 # DOESN'T WORK

我覆盖了 queryset() 方法以控制管理 ListView 的行为。我想在 queryset() 中执行原始 sql 查询,将结果映射回 Item 模型,然后再将它们发送到 ListView 。
问题是返回qs2或qs3会在模板中产生如下错误(不抛出异常):
Database error
Something's wrong with your database installation. Make sure the appropriate database tables have been created, and make sure the database is readable by the appropriate user.

请注意,在单独的脚本中运行原始查询是有效的,例如:
items = Item._default_manager.raw('''
SELECT
"stock_item"."id",
"stock_item"."name",
"stock_item"."unit_cost",
"stock_item"."unit_price"
FROM
"stock_item"
''')

for item in items:
print item.name, item.unit_price # WORKS!

事实上,我有一个更大的野心,能够创建一种不应该有相应数据库表的“虚拟模型”,其目的是将 sql 投影查询封装在其管理类中(以便模型可以显示在它的管理员 ListView 中)。

我尝试了另一种方法,根本不使用 ItemAdmin,而是使用:
class ItemManager(models.Manager):
def get_query_set(self):
return Item._default_manager.raw('''
SELECT
"stock_item"."id",
"stock_item"."name",
"stock_item"."unit_cost",
"stock_item"."unit_price"
FROM
"stock_item"
''')

和:
class Item(models.Model):
objects = ItemManager()
etc...

但现在我在管理 ListView 中收到模板异常:

'RawQuerySet' 对象没有属性 'complex_filter'

该怎么办?谢谢...

最佳答案

解决了。

最简单的方法是在 sqlite3(我正在使用的数据库后端)中创建一个数据库 View ,然后添加一个名称与该 View 兼容的普通模型。模型必须有一组与 View 返回的字段名称相似的字段。我的目的不需要管理员或经理。

查看创建数据库脚本:

CREATE VIEW <view_name> AS SELECT etc...

查看删除数据库脚本(作为初步步骤运行,以防您需要重新创建 View ):
DROP VIEW <view_name>

创建 View 时唯一需要注意的是确保设置:
class Meta:
managed = False
#ordering = ( '-date', )

以免在运行 syncdb 时创建表。

还有一件事,您需要在您的 View 中选择一个唯一的字段作为主键(并在模型中反射(reflect)出来),否则 django 会提示如下:
no such column: stock_itemdbview.id

干杯!

关于Django:如何将原始 sql 查询的结果映射到管理 ListView 中的模型实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8687788/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com