在Django Rest框架中序列化过滤后的相关字段



在我的项目中,我有三个模型:Group,UserChallenge。每个用户都是一些组的成员,每个挑战都针对一个或多个组。

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()将挑战组筛选到仅用户组。为此,您可能还需要传入序列化器上下文

设置序列化程序上下文:

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

使用此实现,您还可以在ChallengeListqueryset上添加prefetch_related('groups')以提高性能

最新更新