如何在django休息中序列化关系?

时间:2016-06-07 07:54:58

标签: json django django-models django-rest-framework

尝试序列化此模型

型号:

    class Order (models.Model):
        id = models.AutoField(primary_key=True)
        date_create = models.DateField(auto_now_add=True)
        date_change = models.DateField(auto_now=True)
        summ =models.CharField(max_length=15,default='0')
        delivery = models.ForeignKey('Delivery')
        success = models.BooleanField(default=False)
        paymentMethod = models.ForeignKey('Payments')
        def __unicode__(self):
            return unicode(self.id)

    class OrderProduct(models.Model):
        order=models.ForeignKey('Order')
        id = models.AutoField(primary_key=True)
        date_create = models.DateField(auto_now_add=True)
        date_change = models.DateField(auto_now=True)
        price = models.IntegerField()
        product = models.ForeignKey('product.Product')
        additionals = models.IntegerField(null=True,default=0)
        count = models.IntegerField()
        def __unicode__(self):
                return self.id


    class Delivery(models.Model):
        id = models.AutoField(primary_key=True)
        date_create = models.DateField(auto_now_add=True)
        date_change = models.DateField(auto_now=True)
        delivery_time = models.DateTimeField()
        delivery_adress = models.TextField()
        phone = models.TextField()
        def __unicode__(self):
                return self.phone

    class Payments(models.Model):
        id = models.AutoField(primary_key=True)
        date_create = models.DateField(auto_now_add=True)
        date_change = models.DateField(auto_now=True)
        title = models.TextField();
        def __unicode__(self):
                return self.title

序列化程序:

class DeliverySerializer(serializers.ModelSerializer):
    class Meta:
        model = Delivery
        fields = ('id', 'delivery_time','delivery_adress','phone')
    def create(self, validated_data):
        return Delivery.objects.create(**validated_data)   


class PaymentsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Payments
        fields = ('id', 'title')
    def create(self, validated_data):
        return Payments.objects.create(**validated_data)   



class OrderSerializer(serializers.ModelSerializer):

    delivery = DeliverySerializer(read_only=True)
    paymentMethod = PaymentsSerializer(read_only=True)
    class Meta:
        model = Order
        fields = ('id', 'delivery', 'paymentMethod','summ','success') 

    def create(self, validated_data):
        deliverys_data = validated_data.pop('delivery')
        paymentsMethod_data = validated_data.pop('paymentMethod')
        order = Order.objects.create(**validated_data)
        for delivery_data in deliverys_data:
            Delivery.objects.create(order=order, **delivery_data)
        for paymentMethod_data in paymentsMethod_data:
            Payments.objects.create(order=order, **paymentMethod_data)
        return order   

查看:

@api_view(['POST'])
def order_post(request, format=None):

   #List all snippets, or create a new snippet.

    if request.method == 'POST':
        serializer = OrderSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我需要通过1个数据包获取数据,然后在DB

中写入数据

EveryTime我收到错误:     deliverys_data = validated_data.pop(' delivery') KeyError:' delivery'

JSON数据包的示例 [{"输送" {" delivery_time":" 2016-05-31T12:18:47Z"" delivery_adress":&#34 ; 123""电话":" 123"}" PAYMENTMETHOD" {" ID":1,"标题":" 123124123"}" SUMM":" 23""成功":假}]

2 个答案:

答案 0 :(得分:0)

  

EveryTime我收到错误:deliverys_data = validated_data.pop('delivery')KeyError:'delivery'

这是预料之中的,因为OrderSerialzier已将DeliverySerializer标记为read_only。 如果要使数据可写,则需要先删除该标志。

答案 1 :(得分:0)

您收到KeyError: 'delivery',因为您已将delivery字段设为read_only。如果DRF在输入中找到此字段,它将忽略该字段。

来自read_only argument:

上的文档
  

只读字段包含在API输出中,但不应包含在API输出中   在创建或更新操作期间包含在输入中。任何   'read_only'字段错误地包含在序列化程序中   输入将被忽略。

此外,由于您在paymentMethod方法中使用create()字段,因此您需要告知DRF在输入中也考虑该字段。

因此,您需要从序列化程序中删除read_onlydelivery字段paymentMethod参数,以便在反序列化时考虑这些字段。< / p>

class OrderSerializer(serializers.ModelSerializer):

    delivery = DeliverySerializer() # remove read_only argument
    paymentMethod = PaymentsSerializer() # remove read_only argument

其次,您发送的数据不正确。您需要发送一个order输入,而不是您要发送的订单列表。

# send without the list 
{"delivery":{"delivery_time":"2016-05-31T12:18:47Z","delivery_adress":"123","phone":"123"},"paymentMethod":{"id":1,"title":"123124123"},"summ":"23","success":false}