Как передать запрос другому сериализатору для валидации

В моей базе данных есть две таблицы для вставки записи о товаре. Я храню информацию о продукте в таблице Product, а остальную информацию, такую как Pirce, Quantity и т.д. храню в другой таблице ProductStock.

Я планирую отправлять данные на сервер примерно следующим образом.

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

Я легко могу подтвердить информацию о продукте из ProductSerializer. Но у меня нет никакой идеальной идеи для проверки данных ProductStockSerializer.

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

Здесь я хочу также проверить информацию product_stock, потому что она приходит с одним запросом. Есть ли способ импортировать ProductStockSerializer в ProductSerializer и передать данные этому сериализатору, а затем проверить их.

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'])

Я буквально не представляю, как это сделать. Спасибо

Как насчет добавления данных ProductStockSerializer в качестве поля в ProductSerializer

class ProductSerializer(serializers.ModelSerializer):
    ...
    product_stock = ProductStockSerializer()

    class Meta:
        fields = [ ... , product_stock ]

Вы должны иметь возможность использовать product_stock в вашей валидации. Если вы планируете создавать ProductStock объекты, используя этот вложенный сериализатор, пожалуйста, обязательно прочитайте о записываемых вложенных сериализаторах.

Ответ @coderiot абсолютно правильный.

Вот как я решил, но в нем гораздо больше кода, чем в приведенном выше ответе.

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)
    stock = serializers.SerializerMethodField(read_only=True)

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

    def get_stock(self,instance):
        return ProductStockSerializer(instance=instance.stock,context=self.context).data

    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.fields['stock'] = ProductStockSerializer(context=self.context)

    def validate(self, attrs):
        request = self.context.get('request')
        attrs['medical'] = Medical.objects.get(pk=request.info.get('medical'))
        return attrs
Вернуться на верх