Reputation: 2087
I want to do the following:
models.py
class MyModel(TimeStampedModel, models.Model):
name = models.CharField(max_length=100)
owner = models.ForeignKey(settings.AUTH_USER_MODEL)
serializers.py
class MyModelSerializerCreate(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = (
'name',
)
And I would like to add as owner the current user in request.user
.
Currently I am adding this in my view directly by uptading request.data with user and then pass the updated data to my serializer.
data = request.data
# Add owner to data
data["owner"] = request.user.pk
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
I would like to do this in my serializer directly but can't find a way to properly do it because it looks like data validation to me. Is this a good idea ? Should I keep this logic in my views or move it to my serializer ?
Upvotes: 10
Views: 19019
Reputation: 8897
You can get a user from serializer context:
self.context['request'].user
It is passed from a method get_serializer_context
which originally created in a GenericAPIView
:
class GenericAPIView(APIView):
....
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}
Inside a serializer you need to override a create
method:
class MyModelSerializerCreate(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ('name', )
def create(self, validated_data):
validated_data['owner'] = self.context['request'].user
return super(MyModelSerializerCreate, self).create(validated_data)
You could also override an update
and delete
methods if you need some special interactions with the User
model.
Upvotes: 22
Reputation: 1813
The solution from Ivan Semochkin did not work for me, as it never entered into the create()
method of the serializer. As request.data
field is immutable, you need to copy it and then extend it.
from django.http import HttpRequest
from rest_framework.request import Request
class MyModelViewSet(ModelViewSet):
def _extend_request(self, request):
data = request.POST.copy()
data['owner'] = request.user
request_extended = Request(HttpRequest())
request_extended._full_data = data
def create(self, request, *args, **kwargs):
request_extended = self._extend_request(request)
return super().create(request_extended, *args, **kwargs)
Upvotes: 2
Reputation: 99
Unfortunatly I dont have the reputation points to comment on @ivan-Semochkin post above, but should the last line not be:
return super(MyModelSerializerCreate, self).create(validated_data)
Upvotes: 4