Сериализация отфильтрованных связанных полей во фреймворке Django Rest
В моем проекте есть три модели: Group
, User
и Challenge
. Каждый пользователь является членом некоторых групп, и каждая задача предназначена для одной или нескольких групп.
class Group(TimeStampedModel):
name = models.CharField(max_length=255)
class User(AbstractUser):
user_groups = models.ManyToManyField(Group)
class Challenge(TimeStampedModel):
...
groups = models.ManyToManyField(Group, null=True, blank=True)
У меня также есть сериализатор для Challenge
моделей, который сериализует все данные вызова и связанные группы с помощью GroupSerializer
.
class ChallengeSerializer(serializers.ModelSerializer):
groups = GroupSerializer(many=True)
class Meta:
model = Challenge
fields = [..., "groups"]
Мой текущий APIView для сериализации списка вызовов.
class ChallengeList(generics.ListAPIView):
queryset = Challenge.objects.all()
serializer_class = ChallengeSerializer
permission_classes = [permissions.IsAuthenticated]
pagination_class = PageNumberPagination
def get_queryset(self):
user_groups = self.request.user.user_groups.all()
return Challenge.objects.filter(groups__in=user_groups).distinct()
При сериализации объекта Challenge
сериализуется список всех связанных групп.
Возможно ли сериализовать только связанные Group
объекты, которые также связаны с нашим текущим вошедшим пользователем?
вы можете использовать SerializerMethodField()
для фильтрации групп Challenges только до групп пользователей. Для этого вам также может понадобиться передать контекст сериализатора
Для настройки контекста сериализатора:
class ChallengeList(generics.ListAPIView):
...
def get_serializer_context(self):
context = {user_groups: self.request.user.user_groups.all()}
return context
...
Затем обратитесь к этому контексту в SerializerMethodField
в вашем сериализаторе
class ChallengeSerializer(serializers.ModelSerializer):
groups_of_user = SerializerMethodField()
class Meta:
model = Challenge
fields = [..., "groups_of_user"]
def get_groups_of_user(self, challenge):
user_groups = self.context.get('user_groups')
groups_of_user = challenge.groups & user_groups
return GroupSerializer(groups_of_user, many=True).data
При такой реализации вы также можете добавить prefetch_related('groups')
на ваши queryset
в ChallengeList
для улучшения производительности