Django Rest Framework Update Data Before Serialization

I want any user to be able to create their own products using my RESTful API. For this purpose, I created a view that inherits ListCreateAPIView. The problem is that the user should only create products that belong to him, so when the product model instance was created, I wanted the owner of the field to match the authenticated user.

Here is my product model

class Product(models.Model):
    owner = models.ForeignKey(User)
    name = models.CharField(max_length=30)

Obviously my serializer:

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Product

and my opinion:

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)

, "initial_data", QueryDict, inmutable. - Python, "owner", (, {'name': ['MyName']}), , , .

+4
3

perform_create() owner. , Product , owner .

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'

, owner read_only. . .

 class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Product
        extra_kwargs = {'owner': {'read_only':True}} # set 'owner' as read-only field 
+4

. owner GET/POST/PUT .., .

from rest_framework.serializers import (CurrentUserDefault, HiddenField,
                                        ModelSerializer)

class ProductSerializer(ModelSerializer):
    owner = HiddenField(default=CurrentUserDefault())

    class Meta:
        model = models.Product
0

You can pass the initial data into the field of view and then overwrite the default value in serializer

views.py

class ItemListCreateView(ListCreateAPIView):

    def get_serializer_context(self):
        return {"delivery_request": self.kwargs['req_pk']}

serializers.py

class ItemCreateSerializer(ModelSerializer):
    delivery_request = CharField(default='')

    def validate_delivery_request(self, value):
        try:
            value = DeliveryRequest.objects.get(
                id=self.context["delivery_request"])
        except DeliveryRequest.DoesNotExist:
            raise ValidationError(
                self.Meta.error_messages['delivery_request_not_found'])
        return value

PS. this is useful if you want to fill non-null data from a url like

0
source

All Articles