DRF:如何验证嵌套序列化器的字段?

时间:2018-09-15 10:35:54

标签: django python-3.x django-models django-rest-framework

我有models,如下所示:

model: Business
    name

model: Employee
    business=FK(Business),
    user = FK(User)

model: Item
    title
    units

model: PurchaseInvoice
    business=FK(Business)
    employee = FK(Employee)
    invoice_no
    date

model: PurchasedItems
    parent_invoice=FK(PurchaseInvoice, related_name="purchased_items")
    item = FK(Item)
    quantity
    rate

serializers.py

class PurchasedItemPOSTSerializer(serializers.ModelSerializer):
    class Meta:
        model = PurchasedItem
        fields = ('item', 'quantity', 'rate')

    def validate_quantity(self, value):
        if value==0 or value is None:
            raise serializers.ValidationError("Invalid quantity")
        return value

    def validate_rate(self, value):
        if value==0 or value is None:
            raise serializers.ValidationError("rate?? Did you get it for free?")
        return value



class PurchaseInvoicePOSTSerializer(serializers.ModelSerializer):
    purchased_items = PurchasedItemPOSTSerializer(many=True)
    class Meta:
        model = PurchaseInvoice
        fields = ('invoice_no','date','purchased_items')

    def validate_purchased_items(self, value):
        if len(value)==0:
            raise serializers.ValidationError("atleast one item is required.")
        return value

    @transaction.atomic
    def create(self, validated_data):
        purchased_items_data = validated_data.pop('purchased_items')
        purchase_invoice = self.Meta.model.objects.create(**validated_data)
        for purchased_item in purchased_items_data:
            PurchasedItem.objects.create(purchase_invoice=purchase_invoice, **purchased_item)
        return invoice

views.py

class PurchaseInvoiceViewSet(viewsets.ModelViewSet):
    serializer_class = PurchaseInvoicePOSTSerializer

    def get_serializer_context(self):
        return {'user': self.request.user, 'business_id': self.kwargs['business_id']}

    def get_queryset(self, **kwargs):
        return PurchaseInvoice.objects.filter(business__id=self.kwargs['business_id'])

    def perform_create(self, serializer):
        business = Business.objects.get(pk=self.kwargs['business_id'])
        employee = get_object_or_404(Employee, business=business, user=self.request.user)
        serializer.save(business=business, employee=employee)

通过POST发送的数据是:

{
    "invoice_no": "123",
    "date": "2018-07-13",
    "purchased_items": [
    {"item":1, "quantity":0, "rate":0}],
}

从上面的数据可以看出,validate_quantity的{​​{1}}不会引发错误,quantity=0的{​​{1}}不会引起validate_rate的错误{1}}。

1 个答案:

答案 0 :(得分:-1)

您可以在序列化器中添加自定义验证。例如:

from rest_framework import serializers
    class PurchasedItemPOSTSerializer(serializers.ModelSerializer):
        class Meta:
            model = PurchasedItem
            fields = ('item', 'quantity', 'rate')

        def validate(self, data):
            # custom anything validate
            quantity = data.get('quantity')
            # recheck validate in this
            if not quantity:
                raise serializers.ValidationError('not valid')
            return data