Reputation: 385
In my app I have the following models: Products, Orders and OrderEntries
Orders are made out of OrderEntries, which represent each row in a shopping cart and are made out of the Product and the amount.
Now, what I want to do with my rest api is the ability to create Order objects by posting an array of OrderEntries to /api/orders, which would validate the array and then create new OrderEntries and the final Order object.
How would I do something like that in rest-framework?
EDIT: How my serializers look like now:
class ProductSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Product
fields = ('pk', 'name', 'author', 'description', 'imageUrl', 'thumbUrl', 'price')
class OrderEntrySerializer(serializers.PrimaryKeyRelatedField, serializers.ModelSerializer):
class Meta:
model = OrderEntry
fields = ("pk", "product", "amount")
class OrderSerializer(serializers.HyperlinkedModelSerializer):
entries = OrderEntrySerializer(many=True, queryset=OrderEntry.objects.all())
class Meta:
model = Order
fields = ("pk", "order_state", "entries")
Which would require me to post the following to /orders:
{
"order_state": "string",
"entries": [
"string"
]
}
What I want is to just post the following, the state field would be set during creation:
{
"entries": [
ProductEntry,
...
]
}
Upvotes: 1
Views: 1053
Reputation: 6296
When you have such a complex relationship you always have to override the serializer's create
method and take care of creating the objects. Checkout DRF Writable Nested Serializers.
A simple solution in your case can be in this form:
class OrderSerializer(serializers.HyperlinkedModelSerializer):
entries = OrderEntrySerializer(many=True, queryset=OrderEntry.objects.all())
class Meta:
model = Order
fields = ("pk", "order_state", "entries")
def create(self, validated_data):
entries = validated_data.pop('entries', None)
order = super().create(validated_data)
for entry in entries:
OrderEntry.objects.create(order=order, **entry)
return order
Of course, this is a very simple solution since I don't have the full details of your models and their relationships but this should give you the idea of what needs to be done. Here, I am assuming that OrderEntry
has a ForeignKey
linked to Order
Upvotes: 3
Reputation: 831
You can try passing your order json objects as a Base64
string.
So, for example:
Let's say your order looks like below:
{
"name" : "Doughnut",
"price" : "1.50"
}
The Base64
encoded version of this would be something like:
ewogICAgICAgICAgICJuYW1lIiA6ICJEb3VnaG51dCIsCiAgICAgICAgICAgInByaWNlIiA6ICIxLjUwIgogICAgICAgIH0=
Now, you can decode this and retrieve order details.
Base64
encoding is a fairly common technique that's used in building web services.
Useful references:
Upvotes: 0