How to get authenticated user in serializer class to check

I am working on a project using django-rest-framework. In my view of the API, an authenticated user can create other users. But only five. Then, if there are five users registered as one user, I want to send it in response, which has reached the limit. Then I need to install an authenticated user on my serializer, but I cannot find a way to transfer it from my ModelViewSet to my serializer.

This is my code:

View:

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, ) 

Serializer:

 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 

Then, in the def validate(self, data) function of my serializer, I want to get the authenticated user.

How can I pass request.user from my APIView to my serializer?

+6
source share
4 answers

I found an even easier way to do this! It turns out that the base class Rest Framework GenericAPIView (from which all classes of the Generic View Framework Rest Framework are dropped) includes the get_serializer_context() function :

 def get_serializer_context(self): """ Extra context provided to the serializer class. """ return { 'request': self.request, 'format': self.format_kwarg, 'view': self } 

As you can see, the returned context object contains the same request object that the View receives. Then this object is set 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) 

Thus, to access the user who executed the request, you just need to call self.context['request'].user from your Serializer validate_ function:

 class TemplateSerializer(serializers.ModelSerializer): def validate_parent(self, value): print(self.context['request'].user) return value class Meta: model = Template 

And most importantly, you don’t need to redefine anything in your ModelViewSet , they can remain as simple as you want:

 class TemplateViewSet(viewsets.ModelViewSet): serializer_class = TemplateSerializer permission_classes = [IsAdmin] 
+8
source

You can pass additional context to your serializer using serializer = ChildUserSerializer(data, context={'request': request}) . You can then access the authenticated user using request.user as part of the serialization method.

+3
source

In djangorestframework> 3.2.4, the rest_framework.generic.GenericAPIView class includes a default HTTP request in the context of a serializer.

So, inside your serializer you can access it: self.context['request'] and user self.context['request'].user

So your ChildUserSerializer will look like this:

 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 ... 
+2
source

In your views, when you initialize a serializer like

serializer = ChildUserSerializer(data=request.DATA,context={'request':request})

send the context containing the request. Then in Serializers inside the function call

request=self.context['request']

Then you can access request.user .

+1
source

Source: https://habr.com/ru/post/984867/


All Articles