【发布时间】:2016-09-14 19:15:31
【问题描述】:
我试图在使用 Django Rest Framework 序列化查询集时优化对查询集进行的查询。
模型分布在不同的应用程序上。
AbstractModels
#core.abstractmodels
class BasicModelMixin(models.Model):
name = models.CharField(max_length=255)
slug = AutoSlugField(max_length=265, unique=True, populate_from='name')
class Meta:
abstract = True
#core.abstractmodels
class ExtraBaseModel(models.Model):
software_license = models.ManyToManyField('meta.License')
class Meta:
abstract = True
以及 languages 应用上的 Language 类,
#languages.models
class Language(BasicModelMixin, ExtraBaseModel):
name = models.CharField(max_length=255, unique=True)
slug = AutoSlugField(max_length=265, unique=True, populate_from='name')
releases = models.ManyToManyField(
'languages.LanguageRelease',
blank=True,
related_name="%(app_label)s_%(class)s_related_releases",
related_query_name="%(app_label)s_%(class)ss_releases")
它有一个从 ExtraBaseModel 继承的 License 字段,即
#meta.License
class License(BasicModelMixin):
display_name = models.CharField(max_length=25)
当我查询 Language 对象时,它会产生额外的重复查询,我需要消除这些查询。
查询如下,
Language.objects.filter(pk=1).prefetch_related('software_license')
在 7ms 内将查询缩短为 4 个,其中 2 个是重复的。 django-debug-toolbar 的输出是,
SELECT *** FROM "languages_language" WHERE "languages_language"."slug" = '''python'''
SELECT *** FROM "meta_license" INNER JOIN
"languages_language_software_license" ON
("meta_license"."id"
= "languages_language_software_license"."license_id")
WHERE
"languages_language_software_license"."language_id"
SELECT *** FROM "meta_license"
Duplicated 2 times.
SELECT *** FROM "meta_license"
Duplicated 2 times.
如何优化查询?必须对模型进行哪些更改才能使其最小化?
Django 版本 = 1.9.x |蟒蛇版本:2.7.11 |数据库:sqlite
更新: 序列化程序(由于我只关心多对多关系而被削减。),
class LanguageSerializer(serializers.ModelSerializer):
class Meta:
model = Language
fields = ('software_license',)
查询跟踪,
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/response.py in rendered_content(71)
ret = renderer.render(self.data, media_type, context)
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/renderers.py in render(676)
context = self.get_context(data, accepted_media_type, renderer_context)
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/renderers.py in get_context(650)
'put_form': self.get_rendered_html_form(data, view, 'PUT', request),
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/renderers.py in get_rendered_html_form(501)
{'style': {'template_pack': 'rest_framework/horizontal'}}
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/renderers.py in render(359)
return template_render(template, context)
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/compat.py in template_render(241)
return template.render(context, request=request)
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/templatetags/rest_framework.py in render_field(38)
return renderer.render_field(field, style)
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/renderers.py in render_field(338)
return template_render(template, context)
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/compat.py in template_render(241)
return template.render(context, request=request)
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/utils/serializer_helpers.py in __getattr__(69)
return getattr(self._field, attr_name)
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/relations.py in choices(493)
return self.child_relation.choices
/home/kate/.virtualenvs/dj19/local/lib/python2.7/site-packages/rest_framework/relations.py in choices(172)
for item in queryset
【问题讨论】:
-
@e4c5 我正在使用 restframework 序列化查询集。
-
好吧,我不是 DRF 方面的专家。请编辑您的问题以反映您使用 DRF 的事实,并考虑更改标签以引起 DRF 专家的注意。
标签: python django django-rest-framework query-optimization django-queryset