Search code examples
pythondjangodjango-modelsdjango-rest-frameworkdjango-serializer

How to Pass the request to another Serializer for Validation


I have two tables in my database to insert a product record. I am storing the product info in the Product table and the rest of the info like Pirce, Quantity etc storing to another table which is ProductStock.

I am planning to send the data to a server something like this.

{
    "name":'product name',
    "brand":"socialcodia"
    "product_stock":{
        "price":"100",
        "quantity":"50"
    }
}

I am easily able to validate the product info from ProductSerializer. But I don't have any perfect idea to validate the ProductStockSerializer data.

ProductSerializer

from rest_framework import serializers
from .models import Product
from .models import Medical

class ProductSerializer(serializers.ModelSerializer):
    
    medical = serializers.CharField(read_only=True)
    id = serializers.CharField(read_only=True)
    is_visible = serializers.CharField(read_only=True,default=True)

    class Meta:
        model = Product
        fields = ['id','medical','category','item','brand','is_visible']

    def validate(self, attrs):
        request = self.context.get('request')
        attrs['medical'] = Medical.objects.get(pk=request.info.get('medical'))
        return attrs

Here I want to validate the product_stock info as well. cuz it's coming with a single request. So is there any way that i can import the ProductStockSerializer into ProductSerializer and pass the data to that serializer. then validate it.

ProductStockSerializer

from rest_framework import serializers
from .models import ProductStock
from medical.models import Medical

class ProductStockSerializer(serializers.ModelSerializer):

    medical = serializers.CharField(read_only=True)
    
    class Meta:
        model = ProductStock
        fields = ['medical','distributer','product','variant','batch','purchase_price','price','quantity','location','low_stock','expire_date']


    def validate(self, attrs):
        
        attrs['medical'] = Medical.objects.get(self.context.get('request').info.get('medical'))
        batch = attrs.get('batch')
        purchase_price = attrs.get('purchase_price')
        price = attrs.get('price'),
        if len(batch) < 3 or len(batch)  > 30:
            raise serializers.ValidationError("Invalid Batch Number")

        if type(purchase_price) != int or type(purchase_price) != float:
            raise serializers.ValidationError("Invalid Purchase Price")

        if type(price) != int or type(price) != float:
            raise serializers.ValidationError("Invalid Price")

        return attrs;

ProductViewSet

class ProductViewSet(ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]


    def get_queryset(self):
        if self.request.user.is_superuser:
            return Product.objects.all()
        return Product.objects.filter(medical=self.request.info['medical'])

I literally don't have any idea how to do this. Thanks


Solution

  • How about adding your ProductStockSerializer data as a field to your ProductSerializer

    class ProductSerializer(serializers.ModelSerializer):
        ...
        product_stock = ProductStockSerializer()
    
        class Meta:
            fields = [ ... , product_stock ]
    

    You should be able to use product_stock in your validation. If you plan to create ProductStock objects using this nested serializer please make sure to read on writable nested serializers.