Reputation: 2334
I am using DRF Writable Nested to create writable nested serializer.
I need to validate 'ItemDetail' but it requires 'product_id' which is present in the parent serializer i.e. 'InvoiceItem'.
Models
class InvoiceItem(models.Model):
product = models.ForeignKey(
Product, on_delete=models.CASCADE, related_name="invoice_items"
)
class ItemDetail(models.Model):
invoice_item = models.ForeignKey(
InvoiceItem, on_delete=models.CASCADE, related_name="item_details"
)
size = models.ForeignKey(
Size, on_delete=models.CASCADE, related_name="item_details"
)
quantity = models.PositiveIntegerField()
Serializers
class InvoiceItemSerializer(WritableNestedModelSerializer):
product = ProductMiniSerializer(read_only=True)
product_id = serializers.IntegerField(write_only=True)
item_details = ItemDetailSerializer(many=True)
class Meta:
model = InvoiceItem
fields = [
"id",
"product_id",
"product",
"item_details",
]
class ItemDetailSerializer(serializers.ModelSerializer):
class Meta:
model = ItemDetail
fields = [
"id",
"size",
"quantity",
]
def validate(self, data):
return item_detail_validate(self, data)
Validator
def item_detail_validate(self, data):
# How to get product_id here so I can use it in a query
return data
Upvotes: 9
Views: 3067
Reputation: 115
This is a little late but for anyone else coming here, use the following when dealing with many=True
def validate(self, data):
product_id = self.parent.parent.initial_data['product_id']
return item_detail_validate(self, data)
Usually when making a related reference, self.parent.initial_data
can fetch the data from the parent serializer. However, when we use many=True
, DRF implicitly calls the ListSerializer
. It passes the child serializer to ListSerializer
, which is then passed to the parent serializer
Reference: https://www.django-rest-framework.org/api-guide/serializers/#listserializer
Upvotes: 8
Reputation: 88499
Access the initial_data
attribute of serializer's parent,
def validate(self, data):
product_id = self.parent.initial_data['product_id']
return item_detail_validate(self, data)
Upvotes: 3