从RawQuerySet返回QuerySet

时间:2013-11-07 12:31:34

标签: django django-admin

我正在尝试从rawqueryset创建一个查询集,但更改列表总是说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.

这是我的尝试(是一个简单的查询,但它会变得更复杂,我需要一个原始的SQL查询):

class MyModelAdmin(admin.ModelAdmin):
    def queryset(self, request):
        qs = MyModel.objects.raw('SELECT field1, field2 FROM MyTable)
        return qs

有没有办法在我的更改列表视图中显示此原始查询,在admin.py中应用admin.site.register(MyModel, MyModelAdmin)

2 个答案:

答案 0 :(得分:7)

已经有一段时间了,从那以后版本似乎发生了很大变化,但是你曾经能够简单地将qs本身转换为字符串或qs中包含的查询属性,它会拼出sql对你而言。

e.g。 sql = str(qs)sql = str(qs.query)

话虽如此,django会修改表名。它可能不是MyTable您正在寻找的,而是appname_my_table。浏览django核心以确切了解命名规范,或者从model_instance._meta.db_name或类似属性获取它。

更新:好吧好像我误解了这个问题,你不想'打印'查询集来检查它生成的sql,你需要ModelAdmin来传递RawQuerySet而不是一个常规的QuerySet到它的ChangeView。

简短的回答:不,它不会那样工作。它们是两个截然不同的类。

看起来它们的行为相同,因为您可以迭代它们,当您这样做时,结果是包含正确的模型实例。然而,它缺少了ModelAdmin的变更视图随着时间的推移而依赖的大量其他功能。我甚至不确定它是否真的有经理。

唯一想到的选择是使用:

  1. 使用Model.objects.extra(...)代替Model.objects.raw(...),以便返回正确的QuerySet。

  2. 使用您的数据库软件,Postgres或MySQL创建一个视图,你有什么。并将其映射到简单的django模型。

  3. 您可以尝试通过将RawQuerySet包装在一个小代理类中来重新创建所有缺少的功能,该代理类将所有内容传递给RawQuerySet并自己实现缺少的方法。我不记得那些是,你可能需要覆盖__and____or__,至少提供一个自定义管理器。我以前做过这个并且很有可能但是我保证很多工作,特别是如果你期望所有常用的管理魔术工作,想想filterspecs,搜索,内联关系。期待伤害你的大脑,或者学会在没有你喜欢的大多数管理员福利的情况下生活。

  4. 问题是,使用raw(...)基本上会导致与django的ORM完全分离,即使乍一看它也让你误以为并非如此(主要是因为它的迭代器返回正确的Model实例)。当然,您的ModelAdmin的ChangeView对于如何处理它没有丝毫的线索。

    亲切的问候,

答案 1 :(得分:1)

您可以创建一个子类models.Manager,并在where子句中创建一个将原始SQL作为子查询执行的方法。

https://gist.github.com/carymrobbins/8477219