加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Django:如何将原始sql查询的结果映射到管理列表视图中的模型实

发布时间:2020-12-20 13:25:59 所属栏目:Python 来源:网络整理
导读:考虑简单的模型: 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.mo
考虑简单的模型:

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"."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"."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"."unit_price"
        FROM
            "stock_item"
        ''')

有:

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

但是现在我在管理列表视图中收到模板异常:

‘RawQuerySet’对象没有属性’complex_filter’

该怎么办?谢谢…

解决方法

解决了.

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

查看创建数据库脚本:

CREATE VIEW <view_name> AS SELECT etc...

查看删除db脚本(在需要重新创建视图时作为预备步骤运行):

DROP VIEW <view_name>

创建视图时,唯一需要注意的是确保设置:

class Meta:
    managed = False
    #ordering = ( '-date',)

以便在运行syncdb时不创建表.

还有一件事,你需要在视图中选择一个唯一的字段作为主键(并在模型中反映出来),否则django会抱怨类似于:

no such column: stock_itemdbview.id

干杯!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读