我有一种情况,其中序列化器字段的值取决于当前登录用户的身份。我已经看到了在初始化序列化程序时如何将用户添加到上下文中,但是我不确定在使用ViewSet时如何执行此操作,因为您只提供序列化程序类而不是实际的序列化程序实例。
基本上我想知道如何去:
class myModelViewSet(ModelViewSet):
queryset = myModel.objects.all()
permission_classes = [DjangoModelPermissions]
serializer_class = myModelSerializer
为:
class myModelSerializer(serializers.ModelSerializer):
uploaded_by = serializers.SerializerMethodField()
special_field = serializers.SerializerMethodField()
class Meta:
model = myModel
def get_special_field(self, obj):
if self.context['request'].user.has_perm('something.add_something'):
return something
对不起,如果不清楚,来自DOC: Adding Extra Context 哪个说要做
serializer = AccountSerializer(account, context={'request': request})
serializer.data
但我不确定如何从视图集中自动执行此操作,因为我只能更改序列化程序类,而不是序列化程序实例本身。
答案 0 :(得分:67)
GenericViewSet
包含您可以覆盖的get_serializer_context
方法:
class myModelViewSet(ModelViewSet):
queryset = myModel.objects.all()
permission_classes = [DjangoModelPermissions]
serializer_class = myModelSerializer
def get_serializer_context(self):
return {'request': self.request}
答案 1 :(得分:1)
在覆盖函数get_serializer_context
中返回父上下文将使访问请求及其数据变得容易。
class myModelViewSet(ModelViewSet):
queryset = myModel.objects.all()
permission_classes = [DjangoModelPermissions]
serializer_class = myModelSerializer
def get_serializer_context(self):
"""
pass request attribute to serializer
"""
context = super(myModelViewSet, self).get_serializer_context()
return context
这非常稳定,因为每次我们请求viewset时,它都会返回上下文。
答案 2 :(得分:1)
在视图集中使用get_serializer()
def get_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
答案 3 :(得分:0)
序列化程序字段的值取决于当前登录用户的标识
这就是我在ModelViewSet中处理这种情况的方法:
def perform_create(self, serializer):
user = self.request.user
if user.username == 'myuser':
serializer.data['myfield'] = 'something'
serializer.save()
答案 4 :(得分:0)
对于基于功能的视图,您可以按照以下方式传递请求或用户:
serializer = ProductSerializer(context = {'request':request},data=request.data)
您的序列化器可能如下所示:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ['id']
def create(self, validated_data):
user = self.context['request'].user
print("User is")
print(user)
请随时告知是否还有更好的方法。