When building APIs with Django Rest Framework (DRF), we often need to access details about the currently authenticated user in our serializers and views. DRF provides easy access to the current request in views, but accessing it in serializers requires a small tweak. In this post, we’ll explore a few ways to access the request.user
in DRF serializers.
Why Access the User in Serializers?
First, why would we need the current user in a serializer? Here are some common use cases:
- Validating that the user has permission to create/update a model instance
- Setting model fields like
created_by
andupdated_by
automatically - Serializing relationships where the user context matters, like foreign keys to the user model itself
By having the user available in serializers, we keep this crucial context available throughout the process.
The Request Object Isn’t Automatically Available
DRF serializers have context available in operations like .create()
and .update()
. However, the request is not included by default. So how can we access it?
1. Add the User Explicitly on Each Request
One method is passing the user explicitly whenever we instantiate the serializer:
serializer = MySerializer(data=data, context={'request': request})
Then inside the serializer’s methods, we can access self.context['request']
to get the user.
This works, but it requires changing every view to pass the request context. It also hides it away inside context
, separate from the data itself.
2. Bind the Request in Serializers Method
Another approach is binding the request inside a custom .bind()
method on the serializer class:
def bind(self, field_name, parent):
super().bind(field_name, parent)
self.request = self.context.get('request')
We can then reference self.request
elsewhere in the serializer. By convention, DRF sets the request in context
, which we pull out and bind to the instance.
This centralizes the wiring, but still separates the user from the main data arguments. We can improve that next.
3. Add the User as a Hidden Field
Finally, we can explicitly add the user as a write-only field called something like current_user
:
class MySerializer(serializers.ModelSerializer):
current_user = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
# ...
def validate(self, data):
user = data['current_user']
# Validate user has permission, etc
Now the user gets passed directly as part of the data, avoiding context completely. We can access it on self
just like any other field for validation, saving relationships, etc.
This binds it closest to the data, avoids repetition, and mirrors how DRF handles the user in the views. By convention, DRF also uses the CurrentUserDefault
field to inject the user.
Conclusion
Accessing the current request and authenticated user from Django Rest Framework serializers requires a small tweak since it’s not included by default.
As we saw, there are a few good options:
- Pass Explicitly – Simple, but repetitive
- Bind in Serializer – Reuses context, but separate from data
- Add as Hidden Field – Treats user like other fields, avoids context
Overall, adding a write-only current_user
field keeps things DRY and readable for accessing users in serializers.
Hopefully this gives you some ideas on how to properly bring request context into DRF serializers!