我有一些奇怪的问题,这是由于Django管理面板想要构建一个查询来显示项目列表并忽略我的提示。它发出包含JOIN
的查询,即使我希望它避免它们以便为底层数据库后端节省大量工作。
基本上考虑3种型号:
Book
BookTemplate
Author
Book
有一些重列(包含整本书),而BookTemplate
有类似的内容(例如,它包含布局的定义,然后填充内容并创建Book
)。
结构类似于:
class Author(models.Model):
uuid = django_extensions.db.fields.UUIDField(primary_key=True)
created = django_extensions.db.fields.CreationDateTimeField(db_index=True)
name = models.CharField(max_length=255)
class BookTemplate(models.Model):
uuid = django_extensions.db.fields.UUIDField(primary_key=True)
created = django_extensions.db.fields.CreationDateTimeField(db_index=True)
content = models.TextField()
class Book(models.Model):
uuid = django_extensions.db.fields.UUIDField(primary_key=True)
created = django_extensions.db.fields.CreationDateTimeField(db_index=True)
content = models.TextField()
template = models.ForeignKey('BookTemplate')
author = models.ForeignKey('Author')
当访问Django管理页面列出Book
个实例时,Django会发出如下数据库调用,这一切都很好(如果不是这样的话):
SELECT
"myapp_book"."uuid", "myapp_book"."content", (...)
INNER JOIN
"myapp_booktemplate"
ON ("myapp_book"."template_id" = "myapp_booktemplate"."uuid")
INNER JOIN
"myapp_author"
ON ("myapp_book"."author_id" = "myapp_author"."uuid")
ORDER BY
"myapp_book"."created" DESC,
"myapp_book"."uuid" DESC;
这个查询的问题在于,由于MySQL的处理方式,它会导致创建巨大的临时表。我想摆脱JOIN
s。
然而,用这样的东西覆盖ModelAdmin.queryset()
无济于事:
class BookModelAdmin(ModelAdmin):
def queryset(request):
return super(BookModelAdmin, self).queryset(request).prefetch_related(
'author', 'template',
)
选中后,家长的.queryset()
方法会返回尚未包含任何需要QuerySet
的条件的JOIN
。
我想:
Book
个实例,以便在没有JOIN
的情况下使用查询(或查询)执行此操作,uuid
的默认排序(这很愚蠢,因为此值完全是随机的),我错过了什么?有没有一些标准的方法呢?我想节省编写管理面板自定义实现的时间,我相信其他人也会遇到类似的问题。