Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get current user in Model Serializer

Is it possible to get the current user in a model serializer? I'd like to do so without having to branch away from generics, as it's an otherwise simple task that must be done.

My model:

class Activity(models.Model):     number = models.PositiveIntegerField(         blank=True, null=True, help_text="Activity number. For record keeping only.")     instructions = models.TextField()     difficulty = models.ForeignKey(Difficulty)     categories = models.ManyToManyField(Category)     boosters = models.ManyToManyField(Booster)      class Meta():         verbose_name_plural = "Activities" 

My serializer:

class ActivitySerializer(serializers.ModelSerializer):      class Meta:         model = Activity 

And my view:

class ActivityDetail(generics.RetrieveUpdateDestroyAPIView):      queryset = Activity.objects.all()     serializer_class = ActivityDetailSerializer 

How can I get the model returned, with an additional field user such that my response looks like this:

{     "id": 1,      "difficulty": 1,      "categories": [         1     ],      "boosters": [         1     ],     "current_user": 1 //Current authenticated user here } 
like image 358
Jamie Counsell Avatar asked Jan 14 '15 02:01

Jamie Counsell


People also ask

What is the difference between serializer and model serializer?

The ModelSerializer class is the same as a regular Serializer class, except that: It will automatically generate a set of fields for you, based on the model. It will automatically generate validators for the serializer, such as unique_together validators. It includes simple default implementations of .

What does a serializer return?

Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

What is hyperlinked serializer?

HyperlinkedModelSerializer is a layer of abstraction over the default serializer that allows to quickly create a serializer for a model in Django. Django REST Framework is a wrapper over default Django Framework, basically used to create APIs of various kinds.

What does serializer Is_valid do?

is_valid perform validation of input data and confirm that this data contain all required fields and all fields have correct types. If validation process succeded is_valid set validated_data dictionary which is used for creation or updating data in DB.


2 Answers

I found the answer looking through the DRF source code.

class ActivitySerializer(serializers.ModelSerializer):          # Create a custom method field     current_user = serializers.SerializerMethodField('_user')      # Use this method for the custom field     def _user(self, obj):         request = self.context.get('request', None)         if request:             return request.user      class Meta:         model = Activity         # Add our custom method to the fields of the serializer         fields = ('id','current_user') 

The key is the fact that methods defined inside a ModelSerializer have access to their own context, which always includes the request (which contains a user when one is authenticated). Since my permissions are for only authenticated users, there should always be something here.

This can also be done in other built-in djangorestframework serializers.

As Braden Holt pointed out, if your user is still empty (ie _user is returning None), it may be because the serializer was not initialized with the request as part of the context. To fix this, simply add the request context when initializing the serializer:

serializer = ActivitySerializer(     data=request.data,     context={         'request': request     } ) 
like image 57
Jamie Counsell Avatar answered Sep 21 '22 20:09

Jamie Counsell


A context is passed to the serializer in REST framework, which contains the request by default. So you can just use self.context['request'].user inside your serializer.

like image 33
codwell Avatar answered Sep 20 '22 20:09

codwell