简体   繁体   English

在Django Rest Framework 3中验证复杂的嵌套对象

[英]Validation of complex nested objects in Django Rest Framework 3

My situation: The client needs to PUT a deep object graph to my Rest Framework 3-powered server, and there are lots of validation rules that need to be applied to the incoming data. 我的情况:客户端需要将一个深层的对象图放置到我的Rest Framework 3驱动的服务器上,并且有很多验证规则需要应用于传入的数据。 For example, imagine incoming JSON like so (this is a contrived example): 例如,想象这样的传入JSON(这是一个人为的示例):

{  // a sales order
    dateOrdered: '2015-02-04T13:23:00-800',
    customer: 5400,  // the customer ID
    items: [
        {
            sku: "TV100",  // the stock item ID
            quantity: 1,
        },
        {
            sku: "HDMI04",  // the stock item ID
            quantity: 3,
        }
    ]
}

And the following serializers: 和以下序列化器:

class OrderSerializer(ModelSerializer):
    dateOrdered = DateTimeField()
    customer = PrimaryKeyRelatedField(queryset=Customer.objects.all())
    items = OrderItemSerializer(many=True)
    class Meta:
        model = Order
    def validate(self, data):
        # see my question below

class OrderItemSerializer(ModelSerializer):
    sku = PrimaryKeyRelatedField(queryset=Item.objects.all())
    quantity = IntegerField()
    class Meta:
        model = OrderItem

The validate() method will receive a Python dict that is a mix of dict s, list s, and Model objects, like so: validate()方法将接收一个python dict ,它是dictlist和Model对象的混合体,如下所示:

data = {
    'dateOrdered':  datetime.datetime(...)
    'customer':  <Customer.object at 0x....>
    'items': [
        {
            'sku': <Item.object at 0x....>
            'quantity': 1,
        },
        {
            'sku': <Item.object at 0x....>
            'quantity': 3,
        }
    ]
}

My problem: validating this "mixed" data structure is ugly (especially in my actual application, where the data structure is much deeper and more complex). 我的问题是:验证这种“混合”数据结构很丑陋(尤其是在我的实际应用中,数据结构更深,更复杂)。 I and future maintainers need to remember which "nodes" are Model objects vs dict s; 我和未来的维护者需要记住哪些“节点”是Model对象与dict the list s and dict s have no business logic methods to help with the validation; listdict没有帮助验证的业务逻辑方法; etc. 等等

It would be much nicer to get the "final" object graph of Django models and just call clean() on that -- doing so would allow me to implement my validation logic in the models themselves, taking advantage of the object graph, allowing reuse of the validation logic in other contexts, etc. 获得Django模型的“最终”对象图并对其调用clean()会更好得多-这样做将允许我利用对象图在模型本身中实现验证逻辑,从而允许重用在其他情况下的验证逻辑等

My question: does anyone have any experience with complex validation like this, and if so, do you have any advice or best practices you can share? 我的问题:有人在这种复杂的验证方面有任何经验吗?如果是,您有什么建议或最佳做法可以分享吗?

Thanks! 谢谢!

I think you can try to create items in sub-serilizers: 我认为您可以尝试在子序列化程序中创建项目:

class OrderItemSerializer(ModelSerializer):
    sku = PrimaryKeyRelatedField(queryset=Item.objects.all())
    quantity = IntegerField()
    class Meta:
        model = OrderItem

    def to_internal_value(self, data):
        item = OrderItem(sku=data['sku'], quantity=data['quantity'])
        item.clean()
        return {'item': item}

Then you will receive something like this: 然后,您将收到如下内容:

data = {
    'dateOrdered':  datetime.datetime(...)
    'customer':  <Customer.object at 0x....>
    'items': [
        {
            'item': <OrderItem.object>
        },
        {
            'item': <OrderItem.object>
        }
    ]
}

Warning: new OrderItemSerializer is quite specific and can be used only as nested serializer. 警告:新的OrderItemSerializer非常具体,只能用作嵌套序列化程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM