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