Last active
August 31, 2022 14:23
-
-
Save ar45/18d654d1aacbb9497241 to your computer and use it in GitHub Desktop.
Dynamic QuerySet serializer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework import serializers | |
from django.db.models.manager import Manager | |
from django.db.models.query import QuerySet | |
class LimitQuerySetSerializerFieldMixin: | |
""" | |
Serializer mixin with a special `get_queryset()` method that lets you pass | |
a callable for the queryset kwarg. This enables you to limit the queryset | |
based on data or context available on the serializer at runtime. | |
""" | |
def get_queryset(self): | |
""" | |
Return the queryset for a related field. If the queryset is a callable, | |
it will be called with one argument which is the field instance and | |
should return a queryset or model manager. | |
.. code:: | |
def get_my_limited_queryset(field): | |
root = field.root | |
if root.instance is None: | |
return MyModel.objects.none() | |
return root.instance.related_set.all() | |
MySerializer(queryset=get_my_limited_queryset) | |
""" | |
# noinspection PyUnresolvedReferences | |
queryset = self.queryset | |
if hasattr(queryset, '__call__'): | |
queryset = queryset(self) | |
if isinstance(queryset, (QuerySet, Manager)): | |
# Ensure queryset is re-evaluated whenever used. | |
# Note that actually a `Manager` class may also be used as the | |
# queryset argument. This occurs on ModelSerializer fields, | |
# as it allows us to generate a more expressive 'repr' output | |
# for the field. | |
# Eg: 'MyRelationship(queryset=ExampleModel.objects.all())' | |
queryset = queryset.all() | |
return queryset | |
class DynamicQuersetPrimaryKeyRelatedField(LimitQuerySetSerializerFieldMixin, serializers.PrimaryKeyRelatedField): | |
"""Evaluates callable queryset at runtime.""" | |
pass |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework import serializers | |
from .custom_serializers import DynamicQuersetPrimaryKeyRelatedField | |
class MyModelSerializer(serializers.ModelSerializer): | |
""" | |
MyModel serializer with a primary key related field to 'MyRelatedModel'. | |
""" | |
def get_my_limited_queryset(self): | |
root = self.root | |
if root.instance is None: | |
return MyRelatedModel.objects.none() | |
return root.instance.related_set.all() | |
my_related_model = DynamicQuersetPrimaryKeyRelatedField(queryset=get_my_limited_queryset) | |
class Meta: | |
model = MyModel |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment