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
CodePudding user response:
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.
CodePudding user response:
The @coderiot answer is absolutely right.
Here's How I Solved, But it has a lot more code than the above answer.
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