如何在Django Admin的get_queryset中使用原始SQL?

时间:2018-12-20 15:44:42

标签: python sql django sqlite

我试图在Django Admin中使用Model.objects.raw(),但最终出现一个通用数据库错误:“您的数据库安装有问题。请确保已创建适当的数据库表,并确保该数据库可读取由适当的用户。”

admin.py

class ChapterAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields':['title','shorthand','description',]})
    ]
    list_display = ('shorthand','title')

    def get_queryset(self, request):
        queryset = super(ChapterAdmin, self).get_queryset(request)
        sql = "SELECT * FROM myapp_chapter"
        queryset = Chapter.objects.raw(sql)
        return queryset

models.py

class Chapter(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField(max_length=800, blank=True, null=True)
    shorthand = models.SlugField(max_length=3, unique=True, null=True)

    def __str__(self):
        return self.shorthand

如果将queryset设置为Chapter.objects.all()而不是Chapter.objects.raw(sql),那么所有功能都会起作用,因此我最初认为我的原始SQL不正确。我还读到如果Models.objects.raw()无法返回行,则会发生错误。但是,在SELECT * FROM myapp_chapter中运行dbshell会正常返回所有内容。 如何在Django Admin中使用原始SQL获取查询集?

关于我为什么选择使用原始SQL的上下文,shorthand包含了我需要自然排序的数字和字母数字值的混合物:

1
10
11
4
5
7A
7B

我使用SELECT * FROM myapp_chapter ORDER BY shorthand*1, shorthand在dbshel​​l中获得了想要的结果:

1
4
5
7A
7B
10
11

但是,如果不使用原始SQL,我将找不到找到此结果的方法。 在不使用原始SQL的情况下还有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

从查询中获取SQL并不那么困难:Getting the SQL from a Django QuerySet 不过,这只是很少的正确解决方案,除了调试外,我不建议这样做。

更好的解决方案是通过Django ORM使用extra()或创建一个额外的列(由于后者可以使用索引,因此加载速度更快):Django QuerySet ordering by expression