4

I am currently working on an billing app and require to have orders inside a bill for that I have following two models Bill and orders

 class Bill(Document):
    billNo = IntField(unique=True, blank=False)
    table = ReferenceField('Table',reverse_delete_rule=1)
    orders = EmbeddedDocumentListField('Order', required = False)
    total = models.FloatField()
    discount = models.FloatField(blank=True)
    grandtotal = models.FloatField()
    payment_option =  ReferenceField('PaymentOption',reverse_delete_rule=1)
    paid = models.BooleanField(default=False)

class Order(EmbeddedDocument):
   food = ReferenceField(Food)
   quantity = IntField(required = True)
   complementory = BooleanField(default = False)

and their serializers are as

class OrderSerializer(EmbeddedDocumentSerializer):
   class Meta:
      model = Order
      fields = 'all'
      read_only_fields = ('id',)

class BillSerializer(DocumentSerializer):
   orders = OrderSerializer(many = True)
   class Meta:
       model = Bill
       fields = '__all__'
       read_only_fields = ('id',)

  def create(self, validated_data):
      orders = validated_data.pop('orders')
      bill = Bill.objects.create(**validated_data)
      bill.orders = []

      for order in orders:
          print(order)
          bill.orders.append(order)
      bill.save()
      return bill

But whenever I pass a json like

{
"billNo": "4",
"table":"5a93eb7f59951a3320a0b4d8",
"payment_option":"5a93eddf59951a2fd4dbabe9",
"orders":[{
 "food":"5a93c2c759951a018c5e18b5",
 "quantity":"2",
 "complementory":"False"
}]
}

the bill object is created but the order is not added and it gives the error

mongoengine.errors.ValidationError: ValidationError           (Bill:5a94f76859951a19d4688aeb) 
(Invalid embedded document instance provided to an EmbeddedDocumentField: ['orders'])

I am using django rest framework and since it is mongodb i am using django rest framework mongo engine. What is the actual error and what shall i do?

Prabin Bhandari
  • 143
  • 3
  • 9
  • You don't need to create `OrderSerializer` by hand - DRF-ME will create an `EmbeddedDocumentSerializer` for your `Bill.order` for you automatically. – Boris Burkov Mar 01 '18 at 12:19

2 Answers2

0

Change your OrderSerializer

class OrderSerializer(EmbeddedDocumentSerializer):
   class Meta:
      model = Order
      fields = '__all__'
      read_only_fields = ('id',)
ishita sharma
  • 401
  • 3
  • 15
0

I was able to make it work by changing the Bill Serializer as below

class BillSerializer(DocumentSerializer):
    orders = OrderSerializer(many = True)

    class Meta:
        model = Bill
        fields = '__all__'
        read_only_fields = ('id',)

    def create(self, validated_data):
        orders = validated_data.pop('orders')
        bill = Bill.objects.create(**validated_data)
        bill.orders = []    

        for order in orders:
            bill.orders.append(Order(**order))


        bill.save()

        return bill
Prabin Bhandari
  • 143
  • 3
  • 9