3

I have a json data to save to a django model. When i try to save it, i get all sorts of errors and i have tried to work around it, all to no avail. Please help me i am new to django rest framework. This are the models i am inserting into:

class OrderItemDishItem(SoftDeleteModelBase):
    item = models.ForeignKey(DishItem, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField(default=1)
    price = models.DecimalField(max_digits=5, decimal_places=2,default=0.00)


class OrderItem(SoftDeleteModelBase):
    dish = models.ForeignKey(Dish, on_delete=models.CASCADE)
    items = models.ManyToManyField(OrderItemDishItem, related_name="dish_items")
    quantity = models.PositiveIntegerField(default=1)
    unit_price = models.DecimalField(max_digits=5, decimal_places=2,default=0.00)
    discount_amount = models.DecimalField(max_digits=5, decimal_places=2,default=0.00)
    discount_percent = models.DecimalField(max_digits=5, decimal_places=2,default=0.00)


class Order(SoftDeleteModelBase):
    foodjoint=models.ForeignKey(FoodJoint, on_delete=models.CASCADE, related_name="orders", null=True)
    customer=models.ForeignKey(CustomerProfile,on_delete=models.CASCADE,null=True)
    items = models.ManyToManyField(to=OrderItem, related_name="order")
    total_cost = models.DecimalField(max_digits=5, decimal_places=2,default=0.00)
    discount_amount = models.DecimalField(max_digits=5, decimal_places=2,default=0.00)
    discount_percent = models.DecimalField(max_digits=5, decimal_places=2,default=0.00)

This is my serializer class for each of them:

class OrderItemDishItemSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        many = kwargs.pop('many', True)
        super(OrderItemDishItemSerializer, self).__init__(many=many, *args, **kwargs)

    class Meta:
        model = models.OrderItemDishItem
        fields = '__all__'
        depth = 1

    def create(self, validated_data):
        dish_item = validated_data.pop("items")


        item_obj = models.OrderItemDishItem.objects.create(**item)

        validated_data["items"]=item_obj
        return super().create(validated_data)


class OrderItemSerializer(serializers.ModelSerializer):
    items = OrderItemDishItemSerializer(many=True)

    def __init__(self, *args, **kwargs):
        many = kwargs.pop('many', True)
        super(OrderItemSerializer, self).__init__(many=many, *args, **kwargs)

    class Meta:
        model = models.OrderItem
        fields = '__all__'

    def create(self, validated_data):
        items = validated_data.pop("items")
        for order in items:
            item =  OrderItemDishItemSerializer(data=order["items"])
            models.OrderItem.objects.create(
                item_id= item.initial_data,
                quantity= order["quantity"],
                unit_price=order['unit_price']
            )
        validated_data["items"]=item.initial_data
        return super().create(validated_data)

class OrderSerializer(serializers.ModelSerializer):
    customer = CustomerSerializer()
    items = OrderItemSerializer(many=True)
    class Meta:
        model = models.Order
        fields = '__all__'
        depth = 1
    def create(self, validated_data):
        user_account= validated_data["customer"].pop("user_account")
        # user_account['password'] = make_password(user_account['password'])
        user = User.objects.create_user(**user_account)

        customer = validated_data.pop("customer")

        customer = models.CustomerProfile.objects.create(
            mobile_number= customer["mobile_number"],
            address= customer["address"],
            user_account= user
        )

        # add OrderItems
        order_items = validated_data.pop("items")
        items =  OrderItemSerializer(data=order_items)

        validated_data["items"] = items.initial_data
        validated_data["customer"] = customer
        # validated_data["customer"]["user_account"] = user
        return super().create(validated_data)

And this is the json data i am posting:

{
  "foodjoint_id": 1,
  "customer": {
    "mobile_number": 2013717123,
    "address": "Sunyani",
    "picture": null,
    "user_account": {
      "username": 2013717123,
      "first_name": "Rahman",
      "last_name": "Lawal",
      "email": "[email protected]",
      "password": "test1234"
    }
  },
  "items": [
    {
      "items": [
        {
          "quantity": 1,
          "price": 22,
          "item": 2
        },
        {
          "quantity": 1,
          "price": 10,
          "item": 4
        },
        {
          "quantity": 1,
          "price": 2,
          "item": 6
        },
        {
          "quantity": 1,
          "price": 0,
          "item": 12
        },
        {
          "quantity": 1,
          "price": 0,
          "item": 13
        },
        {
          "quantity": 1,
          "price": 5,
          "item": 9
        }
      ],
      "unit_price": 22,
      "quantity": 1,
      "dish": 2
    }
  ],
  "total_cost": 0,
  "discount_amount": 0,
  "discount_percent": 0

}

Please how do i save data?

Errors I get:

When a serializer is passed a `data` keyword argument you must call `.is_valid()` before attempting to access the serialized `.data` representation.
You should either call `.is_valid()` first, or access `.initial_data` instead.
3
  • What are the errors you get? Commented Aug 24, 2018 at 15:29
  • I just update the question with the errors please Commented Aug 24, 2018 at 15:31
  • Before keying into your serialized data, try calling is valid on the data you passed in. Commented Aug 24, 2018 at 15:38

2 Answers 2

1

Before keying into your serialized data, try calling is valid on the data you passed in.

items = OrderItemSerializer(data=order_items)
if items.is_valid():
    validated_data["items"] = items.initial_data
    validated_data["customer"] = customer
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you hancho, that only solved part of my problem. Data that should go into the OrderItem model and the OrderItemDishItem are not being populated.
1

I later found out how to do it with the help of the rest-framework documentation http://www.django-rest-framework.org/api-guide/relations/#nested-relationships

class OrderSerializer(serializers.ModelSerializer):
    customer = CustomerSerializer()
    items = OrderItemSerializer(many=True)
    class Meta:
        model = models.Order
        fields = ('id','foodjoint_id','items','customer','total_cost','discount_amount','discount_percent')
        depth = 1

    def create(self, validated_data):
        # get our user info
        customer= validated_data.pop("customer")
        # get order_items
        order_items = validated_data.pop("items")
        # get user info from customer 
        user_account = customer.pop("user_account")
        # create user [1]
        user = User.objects.create_user(**user_account)

        # create customer [2]
        customer['user_account']=user
        customer_instance = models.CustomerProfile.objects.create(**customer)

        order_items_created=[]
        for item in order_items:
            # get order items dish items
            order_items_dish_items = item.pop("items")
            order_item_instance = models.OrderItem.objects.create(**item)
            for order_item_data in order_items_dish_items:
                # create orderitemdishitem [3]
                # dish_item_instance = models.DishItem.objects.filter(id=order_item_data['dish_item_item']).first()
                order_item_instance.items.add(models.OrderItemDishItem.objects.create(**order_item_data))
            # create order item [4]
            order_items_created.append(order_item_instance)
            
        # create order [5]
        order_instance =   models.Order.objects.create(customer=customer_instance,**validated_data)
        order_instance.items.set(order_items_created)
        return order_instance

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.