我正在使用django-rest-framework处理项目。在我的API视图中,经过身份验证的用户可以创建其他用户。但是,只有五个。然后,如果有一个用户注册了五个用户,我想在达到限制的响应中发送给他。然后,我需要让我的序列化程序获得经过身份验证的用户,但是,我无法找到将其从我的ModelViewSet传递到序列化程序的方法。
这是我的代码:
查看:
class ChildUserViewSet(viewsets.ModelViewSet):
serializer_class = ChildUserSerializer
queryset = User.objects.all()
authentication_classes = (
TokenAuthentication,
)
permission_classes = (
IsAuthenticated,
)
def perform_create(self, serializer):
account_group = self.request.user.userprofile.get_account_group
mobile_number = serializer.data.get('mobile_number')
password = serializer.data.get('password')
user = serializer.save()
user.set_password(password)
user.save()
# Generate user profile
UserProfile.objects.create(
user=user,
mobile_number=mobile_number,
user_type=CHILD,
related_account_group=account_group,
)
串行:
class ChildUserSerializer(serializers.ModelSerializer):
mobile_number = serializers.CharField()
class Meta:
model = User
fields = (
'first_name',
'last_name',
'email',
'password',
'mobile_number',
)
def validate(self, data):
"""
Check that the start is before the stop.
"""
# Get authenticated user for raise hit limit validation
def validate_email(self, value):
if User.objects.filter(email=value):
raise serializers.ValidationError("This field must be unique.")
return value
def create(self, validated_data):
username = generate_unique_username(
u'{0}{1}'.format(
validated_data['first_name'],
validated_data['last_name'],
)
)
user = User(
username=username,
first_name=validated_data['first_name'],
last_name=validated_data['last_name'],
email=validated_data['email'],
)
user.set_password(validated_data['password'])
user.save()
return user
然后,在我的序列化程序的def validate(self, data)
函数中,我想获得当前经过身份验证的用户。
如何将request.user从我的APIView传递给我的序列化程序?
答案 0 :(得分:10)
我找到了一种更简单的方法来实现这一目标!事实证明,Rest Framework的GenericAPIView
基类(所有Rest Framework的通用View
类都从中下降)includes a function called get_serializer_context()
:
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}
如您所见,返回的context
对象包含View接收的相同request
对象。然后,此对象将设置为when the serializer is initialized:
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)
因此,要访问发出请求的用户,您只需在序列化程序的self.context['request'].user
函数中调用validate_
:
class TemplateSerializer(serializers.ModelSerializer):
def validate_parent(self, value):
print(self.context['request'].user)
return value
class Meta:
model = Template
最好的部分是你不必覆盖ModelViewSet
中的任何内容,它们可以保持原样:
class TemplateViewSet(viewsets.ModelViewSet):
serializer_class = TemplateSerializer
permission_classes = [IsAdmin]
答案 1 :(得分:3)
您可以使用serializer = ChildUserSerializer(data, context={'request': request})
将其他上下文传递给序列化程序。然后,您可以通过序列化验证方法中的request.user
访问经过身份验证的用户。
答案 2 :(得分:2)
在djangorestframework> 3.2.4 rest_framework.generic.GenericAPIView
类默认在序列化程序上下文中包含http请求。
因此,在序列化程序中,您可以通过以下方式访问它:self.context['request']
和用户self.context['request'].user
所以你的ChildUserSerializer看起来像是:
class ChildUserSerializer(serializers.ModelSerializer):
mobile_number = serializers.CharField()
....
def validate(self, data):
"""
Check that the start is before the stop.
"""
# Get authenticated user for raise hit limit validation
user = self.context['request'].user
# do something with the user here
def validate_email(self, value):
if User.objects.filter(email=value):
raise serializers.ValidationError("This field must be unique.")
return value
...
答案 3 :(得分:1)
在初始化序列化工具时的视图中
serializer = ChildUserSerializer(data=request.DATA,context={'request':request})
,发送一个包含request的上下文。然后在函数调用中的Serializers中
request=self.context['request']
然后您可以访问request.user
。