考虑简单模型:
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()方法,以便控制管理列表视图的行为。我想在queryset()中执行原始sql查询,在将结果发送到列表视图之前将结果映射回Item模型。 问题是返回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投影查询(以便模型可以显示在它的管理列表视图中。
我尝试过另一种方法,根本不使用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...
但现在我在管理列表视图中收到模板异常:
'RawQuerySet'对象没有属性'complex_filter'
怎么办?感谢...
答案 0 :(得分:1)
解决。
最简单的方法是在sqlite3(我正在使用的db后端)中创建数据库视图,然后添加一个名称与视图兼容的普通模型。模型必须具有一组字段,这些字段的名称与视图返回的字段的名称相似。我的目的不需要管理员或经理。
查看创建数据库脚本:
CREATE VIEW <view_name> AS SELECT etc...
查看删除数据库脚本(如果需要重新创建视图,则作为预备步骤运行):
DROP VIEW <view_name>
创建视图时,唯一需要注意的是确保设置:
class Meta:
managed = False
#ordering = ( '-date', )
以便在运行syncdb时不创建表。
还有一件事,你需要在视图中选择一个唯一的字段作为主键(并在模型中反映出来),否则django会抱怨像:
no such column: stock_itemdbview.id
干杯!
答案 1 :(得分:0)