I want that any user could create their own products with my RESTful API. For this purpose, I created a view that inherits ListCreateAPIView. The problem is that a user should only create products that he/she own, so when the instance of the Product model is created, I wanted that the field Owner corresponds to the user that is authenticated.
Here's my Product model
class Product(models.Model):
    owner = models.ForeignKey(User)
    name = models.CharField(max_length=30)
Obviously my serializer is:
class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Product
and my view:
class ProductView(generics.ListCreateAPIView):
    queryset = models.Product.objects.all()
    serializer_class = serializers.ProductSerializer
    permission_classes = (IsAuthenticatedOrReadOnly,)
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        #serializer.initial_data['owners'] = models.Person.objects.get(user__email=request.user).user_id
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
As you can see, I tried modifying the "initial_data", but it is a QueryDict, which is inmutable. Another option is transforming it into a Python dict and then adding the "owner" value, but at doing that I get every value as a list (i.e. {'name': ['MyName']}), so it would be a very ugly way to solve the problem, I think it should be a more straightforward solution.
You can override perform_create() and pass the current user as the owner. Then, when the Product instance will be created, owner field will be saved with the current user value.
class ProductView(generics.ListCreateAPIView):
    queryset = models.Product.objects.all()
    serializer_class = serializers.ProductSerializer
    permission_classes = (IsAuthenticatedOrReadOnly,)
    def perform_create(self, serializer):
        serializer.save(owner=self.request.user) # pass the current user as the 'owner'
Also, you should define owner field in your serializer as read_only. Then the field will not be required during deserialization. But, this field will be included in the output on serialization.
 class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Product
        extra_kwargs = {'owner': {'read_only':True}} # set 'owner' as read-only field 
                        Simple solution below. owner will not be visible in request GET/POST/PUT etc. but will be auto assigned to current authenticated user.
from rest_framework.serializers import (CurrentUserDefault, HiddenField,
                                        ModelSerializer)
class ProductSerializer(ModelSerializer):
    owner = HiddenField(default=CurrentUserDefault())
    class Meta:
        model = models.Product
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With