使用Django序列化器类保存嵌套数据

时间:2018-08-24 12:52:17

标签: python-3.x django-models django-rest-framework django-serializer django-2.1

我有一个json数据要保存到Django模型。当我尝试保存它时,出现各种错误,并且尝试解决该问题,但无济于事。请帮助我,我是django rest框架的新手。 这是我要插入的模型:

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)

这是我的每个序列化器类:

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)

这是我要发布的json数据:

{
  "foodjoint_id": 1,
  "customer": {
    "mobile_number": 2013717123,
    "address": "Sunyani",
    "picture": null,
    "user_account": {
      "username": 2013717123,
      "first_name": "Rahman",
      "last_name": "Lawal",
      "email": "email@email.com",
      "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

}

请问我如何保存数据?

我得到的错误:

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.

2 个答案:

答案 0 :(得分:0)

在键入序列化数据之前,请尝试对传入的数据进行调用。

items = OrderItemSerializer(data=order_items)
if items.is_valid():
    validated_data["items"] = items.initial_data
    validated_data["customer"] = customer

答案 1 :(得分:0)

我后来发现如何在其余框架文档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