From 73645772fa5d5962ea57a1a7c58f10d4eb5d8837 Mon Sep 17 00:00:00 2001 From: yezy Date: Tue, 26 Nov 2019 00:11:38 +0300 Subject: [PATCH] :sparkles:Make `EagerLoading` mixin independent of `DynamicFieldsMixin` - Introduce `RequestQueryParserMixin` used by both `DynamicFieldsMixiin` & `EagerLoadingMixin`, Closes #86 - Make query parameter name configurable through settings file, Closes #84 --- django_restql/mixins.py | 74 +++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/django_restql/mixins.py b/django_restql/mixins.py index ddfddfb..ea8cd63 100644 --- a/django_restql/mixins.py +++ b/django_restql/mixins.py @@ -4,7 +4,7 @@ Serializer, ListSerializer, ValidationError ) -from django.db.models import Prefetch +from django.conf import settings from django.db.models.fields.related import( ManyToOneRel, ManyToManyRel ) @@ -18,36 +18,26 @@ ) -class DynamicFieldsMixin(object): - query_param_name = "query" - - def __init__(self, *args, **kwargs): - # Don't pass 'query', 'fields' and 'exclude' kwargs to the superclass - self.query = kwargs.pop('query', None) # Parsed query - self.allowed_fields = kwargs.pop('fields', None) - self.excluded_fields = kwargs.pop('exclude', None) - self.return_pk = kwargs.pop('return_pk', False) - - is_field_kwarg_set = self.allowed_fields is not None - is_exclude_kwarg_set = self.excluded_fields is not None - msg = "May not set both `fields` and `exclude`" - assert not(is_field_kwarg_set and is_exclude_kwarg_set), msg - - # Instantiate the superclass normally - super().__init__(*args, **kwargs) - - def to_representation(self, instance): - if self.return_pk: - return instance.pk - return super().to_representation(instance) +class RequestQueryParserMixin(object): + @staticmethod + def get_query_param_name(): + DEFAULT_QUERY_PARAM_NAME = 'query' + query_param_name = getattr( + settings, + "QUERY_PARAM_NAME", + DEFAULT_QUERY_PARAM_NAME + ) + return query_param_name @classmethod def has_query_param(cls, request): - return cls.query_param_name in request.query_params + query_param_name = cls.get_query_param_name() + return query_param_name in request.query_params @classmethod def get_raw_query(cls, request): - return request.query_params[cls.query_param_name] + query_param_name = cls.get_query_param_name() + return request.query_params[query_param_name] @classmethod def get_parsed_query_from_req(cls, request): @@ -64,6 +54,28 @@ def get_parsed_query_from_req(cls, request): ) raise ValidationError(msg) from None + +class DynamicFieldsMixin(RequestQueryParserMixin): + def __init__(self, *args, **kwargs): + # Don't pass 'query', 'fields' and 'exclude' kwargs to the superclass + self.query = kwargs.pop('query', None) # Parsed query + self.allowed_fields = kwargs.pop('fields', None) + self.excluded_fields = kwargs.pop('exclude', None) + self.return_pk = kwargs.pop('return_pk', False) + + is_field_kwarg_set = self.allowed_fields is not None + is_exclude_kwarg_set = self.excluded_fields is not None + msg = "May not set both `fields` and `exclude`" + assert not(is_field_kwarg_set and is_exclude_kwarg_set), msg + + # Instantiate the superclass normally + super().__init__(*args, **kwargs) + + def to_representation(self, instance): + if self.return_pk: + return instance.pk + return super().to_representation(instance) + def get_allowed_fields(self): fields = super().fields if self.allowed_fields is not None: @@ -268,7 +280,7 @@ def fields(self): return {} -class EagerLoadingMixin(object): +class EagerLoadingMixin(RequestQueryParserMixin): @property def parsed_query(self): """ @@ -276,12 +288,8 @@ def parsed_query(self): Defaults to the serializer parsed query assuming using django-restql DynamicsFieldMixin. """ - if hasattr(self, "get_serializer_class"): - serializer_class = self.get_serializer_class() - - if issubclass(serializer_class, DynamicFieldsMixin): - if serializer_class.has_query_param(self.request): - return serializer_class.get_parsed_query_from_req(self.request) + if self.has_query_param(self.request): + return self.get_parsed_query_from_req(self.request) # Else include all fields query = { @@ -391,7 +399,7 @@ def get_queryset(self): queryset = super().get_queryset() queryset = self.get_eager_queryset(queryset) return queryset - + class NestedCreateMixin(object): """ Create Mixin """