在Django Rest Framework 3

时间:2015-07-04 18:28:00

标签: python django validation django-rest-framework

我的情况:客户端需要将深层对象图提供给我的Rest Framework 3驱动的服务器,并且需要将大量验证规则应用于传入数据。例如,想象传入的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,
        }
    ]
}

以下序列化程序:

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

validate()方法会收到一个Python dict,它混合了dict s,list和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,
        }
    ]
}

我的问题:验证这种“混合”数据结构很难看(特别是在我的实际应用中,数据结构更深,更复杂)。我和未来的维护者需要记住哪些“节点”是模型对象vs dict s; listdict没有业务逻辑方法来帮助验证;等

获取Django模型的“最终”对象图并在其上调用clean()会更好 - 这样做可以让我在模型中实现我的验证逻辑,利用对象图,允许在其他上下文中重用验证逻辑等。

我的问题:有没有人有这样复杂验证的经验,如果有,你有什么建议或最佳实践可以分享吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为您可以尝试在子血清化器中创建物品:

$loc = Read-Host "Enter location"
dir $loc *.xml | 
Select-String -pattern '\([0-9]{3}\) [0-9]{3}-[0-9]{4}' -AllMatches |
Select @{n='Date Time';e={(get-item $_.Path).LastWriteTime.ToString('MM/dd/yyyy hh:mm:ss')}}, @{n=' Phone Number';e={$_.Matches.Value}} |
ft -AutoSize

然后你会收到这样的东西:

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}

警告:新data = { 'dateOrdered': datetime.datetime(...) 'customer': <Customer.object at 0x....> 'items': [ { 'item': <OrderItem.object> }, { 'item': <OrderItem.object> } ] } 非常具体,只能用作嵌套序列化程序。