代码之家  ›  专栏  ›  技术社区  ›  Sreekanth Reddy Balne

drf:如何验证嵌套序列化程序的字段?

  •  0
  • Sreekanth Reddy Balne  · 技术社区  · 6 年前

    我有 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)
    

    邮寄数据为:

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

    从上面的数据可以看出 validate_quantity 什么时候? quantity=0 也不是通过 validate_rate 什么时候? rate=0 对于 item 在里面 purchased_items .

    1 回复  |  直到 6 年前
        1
  •  -1
  •   Pang Ajmal PraveeN    6 年前

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

    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
    
    推荐文章