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. For example, imagine incoming JSON like so (this is a contrived example):
{ // 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 dicts, lists, and Model objects, like so:
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 dicts; the lists and dicts have no business logic methods to help with the validation; 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.
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!