Search code examples
pythondjango-rest-frameworkdjango-serializer

Post a list of objects with the current user in Django Rest Framework


Took me a while get it done, how to post a list/array full of JSON objects with the current user, a lot of mixed answers but this one works for me, I hope this helps someone, keep learning, keep having fun.

Next step is to set up the get_queryset to get orders per user


Solution

  • Post a list of objects to the same order in the order table (check fk_order variable in OrderProductsSerializer).

    There are two many to many tables, OrderModel y ProductModel, so to add more fields I create the OrderProductsModel table and yeah, thats how I approached the situation, lookin for to know if this is bad or good to learn from more experienced professionals and grow , thank you people, cheers

    Open to suggestions to improve and avoid share errors or bad practices, I will be editing answer.

    ############################# models.py######################################
    
    class OrderProductsModel(models.Model):
            quantity_order_product = models.IntegerField(default=0, null=True, blank=True)
            price_order_product = models.FloatField(default=0,null=True, blank=True)
            fk_product = models.ForeignKey(ProductModel, null=True, blank=True, on_delete=models.SET_NULL)
            fk_user = models.ForeignKey(CustomUser, null=True, blank=True, on_delete=models.SET_NULL)
            ...
            ...
            ... more fields
    
    ############################# views.py######################################
    
    class PostOrderProduct(mixins.CreateModelMixin,
                            generics.GenericAPIView):
        
        serializer_class = OrderProductsSerializer
        
        def get_queryset(self):
            return OrderProductsModel.objects.all()
    
        def post(self, request, *args, **kwargs):
            items = request.data
            if isinstance(items, list):
                serializer = self.serializer_class( instance='',
                                                    data=items, 
                                                    many=True, 
                                                    context = {
                                                                "request": self.request,
                                                                }
                                                                )
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
                    return Response(serializer.data, status=status.HTTP_200_OK)
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
            
            elif isinstance(items, dict):
                return self.create(request, *args, **kwargs)
       
    
    ############################# serializers.py ######################################
    class OrderProductsListSerializer(serializers.ListSerializer):
    
        def update(self, instance, validated_data):
            # Perform creations and updates.
            ret = []
            for data in validated_data:
                if data.get('id') not in {'', None}:
                    OrderProductsModel.objects.filter(id=data['id']).update(**data)
                    ret.append(data)
                else:
                    ret.append(OrderProductsModel.objects.create(**data))
            return ret
    
    
    class OrderProductsSerializer(serializers.ModelSerializer):
        fk_user = serializers.HiddenField(default=serializers.CurrentUserDefault())
        fk_order = serializers.HiddenField(default=OrderModel.objects.create())
        
        class Meta:
            model = OrderProductsModel
            list_serializer_class = OrderProductsListSerializer
            fields = ['fk_user', 'quantity_order_product', 'price_order_product', 'fk_product']