Reputation: 1487
I need to handle some JSON data with django. I will receive this data :
{
"user": 8,
"orderDay": "2020-06-24",
"deliveryDay": "2020-06-30",
"deliveryAddress": "Place des Fêtes",
"comment": "",
"orderDetail":
[
{
"product": 2,
"byProduct": 2,
"quantity": 43
},
{
"product": 3,
"byProduct": 3,
"quantity": 5
}
]
}
I would like to save this data in 3 differents table: order and orderDetail. models.py:
class order(models.Model):
user = models.ForeignKey(memberArea, on_delete=models.CASCADE)
comment = models.TextField(null=True, blank=True)
orderDay = models.DateTimeField(auto_now_add=True)
deliveryDay = models.DateField()
deliveryPlace = models.CharField(max_length=255)
state = models.CharField(max_length=255)
price = models.TextField(null=True, blank=True)
response = models.TextField(null=True, blank=True)
...
class orderDetail(models.Model):
order = models.ForeignKey(order, on_delete=models.CASCADE)
product = models.ForeignKey(product, on_delete=models.CASCADE)
byProduct = models.ManyToManyField(byProduct)
quantity = models.CharField(max_length=255)
...
class byProduct(models.Model):
product = models.ForeignKey(product, on_delete = models.CASCADE)
name = models.CharField(max_length=255)
...
class product(models.Model):
name = models.CharField(max_length=255)
prix_uni = models.TextField(null=True, blank=True)
prix_kg = models.TextField(null=True, blank=True)
dispo = models.BooleanField(null=True, blank=True)
category = models.ForeignKey(category, on_delete=models.CASCADE)
redu = models.TextField(null=True, blank=True)
I don't find any good documentation about how to handle JSON data whith Django. Thanks by advance
UPDATE
I tried something like this: serializer.py:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = product
fields = '__all__'
class ByProductSerializer(serializers.ModelSerializer):
class Meta:
model = byProduct
fields = '__all__'
class orderDetailSerializer(serializers.ModelSerializer):
order = serializers.PrimaryKeyRelatedField(many=False, queryset=order.objects.all())
class Meta:
model = orderDetail
fields = '__all__'
class OrderSerializer(serializers.ModelSerializer):
orderDetail = orderDetailSerializer(many=True)
class Meta:
model = order
fields = ['user', 'comment', 'deliveryDay', 'deliveryAddress', 'orderDetail']
def create(self, validated_data):
order_detail_data = validated_data.pop('orderDetail')
new_order = order.objects.create(**validated_data)
new_order.save()
for product in order_detail_data:
order_detail = orderDetail.objects.create(**product)
order_detail.order.add(new_order.id)
return new_order
views.py:
@api_view(['POST'])
def order(request, format=None):
if request.method == 'POST':
serializer = OrderSerializer(data=request.data)
data = {}
if serializer.is_valid():
serializer.save()
data['response'] = "Your order went well"
return Response(data)
return Response(serializer.errors)
Upvotes: 0
Views: 468
Reputation: 424
There are few changes you need to make.
{
"user": 8,
"orderDay": "2020-06-24",
"deliveryDay": "2020-06-30",
"deliveryAddress": "Place des Fêtes",
"comment": "",
"orderDetail":
[
{
"product": 2,
"byProduct": [2],
"quantity": 43
},
{
"product": 3,
"byProduct": [3],
"quantity": 5
}
]
}
byProduct
is a ManyToMany
field so it must have a list of products.
orderDetailSerializer
:class orderDetailSerializer(serializers.ModelSerializer):
class Meta:
model = orderDetail
fields = ['product', 'byProduct', 'quantity']
Take note, in fields
I have not included order
because in our data there is no such field, and hence the error, order field is required
. It's simple because serializer will parse the data we are sending and if there is something missing it will notify us.
orderSerializer
:class OrderSerializer(serializers.ModelSerializer):
orderDetail = orderDetailSerializer(many=True)
class Meta:
model = order
fields = ['user', 'comment', 'deliveryAddress', 'deliveryDay', 'orderDetail']
def create(self, validated_data):
order_detail_data = validated_data.pop('orderDetail')
new_order = order.objects.create(**validated_data)
# new_order.save()
for product in order_detail_data:
by_products = product.pop('byProduct')
order_detail = orderDetail.objects.create(order=new_order, **product)
order_detail.byProduct.set(by_products)
order_detail.save()
return new_order
Few things to notice, fields
include orderDetail
although it is not a part of order
model, but in order to parse the data being passed we need to add such fields, if there are more. Inside create
method byProduct
is a ManyToMany
field, so we will have to use set()
method in order assign them, direct assignment
is not allowed.
Upvotes: 1