0

私がしようとしているのは、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クラス、

ある ExtraBaseModelから継承されたライセンスフィールドを有し
#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") 

私はLanguageオブジェクトを照会するとき

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

、それは私が排除するために必要な追加の重複したクエリを作成します。次のようにクエリが行われる

、2が重複しているその7MS 4にクエリを短縮

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

。 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 version = 1.9.x | Pythonバージョン:2.7.11 | DB: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 
+0

を変更します。 – Rivadiz

+0

私はDRFの専門家ではありません。DRFを使用していることを反映するために質問を編集してください。また、DRFの専門家の注意を引くようにタグを変更することを検討してください。 – e4c5

答えて

0

BrowsableAPIは、多くの場合、表示されます(私は唯一の多対多の関係で心配とトリムダウン。)関連するフィールドは作成/更新フォームに対して独立して照会されるため、重複した照会が必要です。

ログ設定にdjango.db.backendを追加してDjango DBクエリログを有効にし、コンテンツタイプをJSONとして設定するか、読み取り専用のアクセス許可(フォームを無効にする)を使用することができます。

いつか、Django Debugツールバーは評価された方法によってクエリを複製することがあることに注意してください(私はそれを引き起こした正確な条件を覚えていませんが、これでヒットしました)。

0

meta.License

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

に別々のシリアライザを書くには、私はrestframeworkでクエリセットをシリアル化していますe4c5 @あなたのシリアライザ

class LanguageSerializer(serializers.ModelSerializer): 
    software_license = LicenseSerializer(many=True) # make sure you match field name 
    class Meta: 
     model = Language 
     fields = ('software_license',) 
関連する問題