如何消除额外的重复查询?

2024-04-20 02:10:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图优化查询集上的查询,同时使用Django Rest框架序列化queryset。在

这些模型分布在不同的应用程序上。 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

以及应用程序上的Language

^{pr2}$

它有一个从ExtraBaseModel继承的许可证字段

#meta.License
class License(BasicModelMixin):
    display_name = models.CharField(max_length=25)

当我查询Language对象时,它会产生额外的重复查询,我需要消除这些查询。在

查询如下:

Language.objects.filter(pk=1).prefetch_related('software_license')

这将查询缩短到4in7ms,其中2个是重复的。django调试工具栏的输出是

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 version=1.9.x | python版本:2.7.11 | db:sqlite

更新: 序列化程序(因为我只关心manytomy关系,所以被删减了)

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

Tags: inpyresthomelicenselibpackageslocal
2条回答

meta.License编写单独的序列化程序

class LicenseSerializer(serializers.ModelSerializer):
    class Meta:
        model = License
        fields = '__all__' # choose the fields you wish

然后修改序列化程序

^{pr2}$

browsablepi通常会显示重复的查询,因为创建/更新表单的相关字段将被单独查询。在

您可以通过在日志配置中添加^{}来打开Django数据库查询日志记录,并将内容类型设置为JSON,或者使用只读权限(禁用表单)。在

请注意,有时,Django调试工具栏有时会根据查询的计算方式复制查询(我曾经遇到过这个问题,但我记不起导致它的确切条件)。在

相关问题 更多 >