gpt4 book ai didi

python - 在一个 ViewSet 中基于每个对象更改序列化程序?

转载 作者:行者123 更新时间:2023-11-28 18:35:11 24 4
gpt4 key购买 nike

我正在开发一个具有一些社交功能的项目,需要让用户可以看到他个人资料的所有详细信息,但只能看到其他人个人资料的公开部分。
有没有办法在一个 ViewSet 中做到这一点?

这是我的模型示例:

class Profile(TimestampedModel):
user = models.OneToOneField(User)

nickname = models.CharField(max_length=255)
sex = models.CharField(
max_length=1, default='M',
choices=(('M', 'Male'), ('F', 'Female')))

birthday = models.DateField(blank=True, null=True)

例如,对于这个模型,我希望生日保持私密。
在实际模型中大约有十几个这样的字段。

我的序列化器:

class FullProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile


class BasicProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = read_only_fields = ('nickname', 'sex', 'birthday')

我写的自定义权限:

class ProfilePermission(permissions.BasePermission):
"""
Handles permissions for users. The basic rules are

- owner and staff may do anything
- others can only GET
"""

def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
else:
return request.user == obj.user or request.user.is_staff

还有我的观点:

class RUViewSet(
mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
mixins.ListModelMixin, viewsets.GenericViewSet):
"""ViewSet with update/retrieve powers."""


class ProfileViewSet(RUViewSet):
model = Profile
queryset = Profile.objects.all()
permission_classes = (IsAuthenticated, ProfilePermission)

def get_serializer_class(self):
user = self.request.user
if user.is_staff:
return FullProfileSerializer
return BasicProfileSerializer

我想要的是 request.user 在查询集中使用 FullProfileSerializer 序列化自己的配置文件,但其余部分使用 BasicProfileSerializer.
这完全有可能使用 DRF 的 API 吗?

最佳答案

我们可以覆盖 ProfileViewSet 中的 retrieve()list 方法,以根据正在查看的用户返回不同的序列化数据。

list 方法中,我们使用从 get_serializer_class() 方法返回的序列化程序序列化除当前用户之外的所有用户实例。然后我们使用 FullProfileSerializer 显式序列化当前用户配置文件信息,并将此序列化数据添加到之前返回的数据中。

retrieve 方法中,我们在 View 上设置了一个accessed_profile 属性以了解 View 正在显示的用户。然后,我们将在 get_serializer_class() 方法中使用此属性来决定序列化程序。

class ProfileViewSet(RUViewSet):
model = Profile
queryset = Profile.objects.all()
permission_classes = (IsAuthenticated, ProfilePermission)

def list(self, request, *args, **kwargs):
instance = self.filter_queryset(self.get_queryset()).exclude(user=self.request.user)
page = self.paginate_queryset(instance)
if page is not None:
serializer = self.get_pagination_serializer(page)
else:
serializer = self.get_serializer(instance, many=True)
other_profiles_data = serializer.data # serialized profiles data for users other than current user
current_user_profile = <get_the_current_user_profile_object>
current_user_profile_data = FullProfileSerializer(current_user_profile).data
all_profiles_data = other_profiles_data.append(current_user_profile_data)
return Response(all_profiles_data)

def retrieve(self, request, *args, **kwargs):
self.accessed_profile = self.get_object() # set this as on attribute on the view
serializer = self.get_serializer(self.accessed_profile)
return Response(serializer.data)

def get_serializer_class(self):
current_user = self.request.user
if current_user.is_staff or (self.action=='retrieve' and self.accessed_profile.user==current_user):
return FullProfileSerializer
return BasicProfileSerializer

关于python - 在一个 ViewSet 中基于每个对象更改序列化程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33201702/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com