【问题标题】:Django : handle post JSON requestsDjango:处理后 JSON 请求
【发布时间】:2020-10-25 03:02:10
【问题描述】:

我需要用 django 处理一些 JSON 数据。 我会收到这些数据:

{
    "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
        }
    ]
}

我想将此数据保存在 3 个不同的表中:orderorderDetailmodels.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)

我没有找到任何关于如何使用 Django 处理 JSON 数据的好的文档。 提前致谢

更新

我尝试过这样的事情: 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)

【问题讨论】:

  • 与您之前处理请求的方式相同。根据您发布的示例数据,您需要nested serializers。看看here,这不完全适合您的数据,但您会知道如何继续。
  • 另外,如果您想要答案,请确保发布所有相关模型,这样很容易尝试。例如,byProduct 丢失。
  • 谢谢,我会检查你的链接!我已经用副产品模型更新了我的帖子
  • @neferpitou 我试图在你的链接中做类似的事情,我已经用我的更新更新了我的帖子,但不幸的是,它暂时不起作用......
  • product model add that also, 之后我会尝试为模型添加相关的序列化程序。

标签: python json django django-rest-framework django-serializer


【解决方案1】:

您需要进行一些更改。

  1. 更改数据格式:
{
    "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 是一个ManyToMany 字段,因此它必须包含产品列表。

  1. 在你的orderDetailSerializer:
class orderDetailSerializer(serializers.ModelSerializer):

    class Meta:
        model = orderDetail
        fields = ['product', 'byProduct', 'quantity']

请注意,在fields 中我没有包含order,因为在我们的数据中没有这样的字段,因此出现错误order field is required。这很简单,因为序列化程序会解析我们发送的数据,如果缺少某些内容,它会通知我们。

  1. 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

需要注意的一点是,fields 包括 orderDetail 虽然它不是 order 模型的一部分,但是为了解析正在传递的数据,我们需要添加这样的字段,如果有更多的话。在create 方法内部byProduct 是一个ManyToMany 字段,所以我们必须使用set() 方法来分配它们,direct assignment 是不允许的。

【讨论】:

  • 我尝试这样做,但仍然出现此错误:{ "orderDetail": [ { "order": [ "This field is required." ] }, { "order": [ "This field is required." ] } ] }
  • OrderDetailsSerializer里面试试order = serializers.PrimaryKeyRelatedField(many=False, queryset=order.objects.all())
  • 不幸的是我遇到了同样的错误...我用新的 OrderDetailSerializer 更新了我的帖子
  • 我阅读了这个文档:django-rest-framework.org/api-guide/relations/…,也许我得到了这个错误,因为serializers.PrimaryKeyRelatedField(many=False, queryset=order.objects.all()) 的结果是一个列表?或者在我创建 new_order 之前可能有错误?
  • @Bastien 我已经用工作版本更新了这个答案,并从那里删除。因为那里似乎是多余的。此外,任何有类似问题的人都可以轻松关注。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-03
  • 1970-01-01
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 2016-09-07
  • 2011-03-05
相关资源
最近更新 更多