如何使用 Postman 表单数据在 Django REST Framework 中发布嵌套数组?

Posted

技术标签:

【中文标题】如何使用 Postman 表单数据在 Django REST Framework 中发布嵌套数组?【英文标题】:How to post nested arrays in Django REST Framework with Postman form-data? 【发布时间】:2020-06-02 08:58:33 【问题描述】:

我有一个带有数组字段的嵌套可写序列化程序。我需要使用表单数据对其进行测试,因为其中一种字段类型是ImageField。当我将 ImageField 更改为 CharField 时,如果我以原始 JSON 格式发布它,它工作正常。 我的简化版serializers.py

class ProductMarketSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=False)
    market = serializers.PrimaryKeyRelatedField(many=False, queryset=Market.objects.all())
    slabs = serializers.PrimaryKeyRelatedField(many=True, queryset=Slab.objects.all())
    thicknesses = serializers.PrimaryKeyRelatedField(many=True, queryset=Thickness.objects.all())
    finish_types = serializers.PrimaryKeyRelatedField(many=True, queryset=FinishType.objects.all())

    class Meta:
        model = ProductMarket
        fields = ['id', 'market', 'name', 'slabs', 'thicknesses', 'finish_types']


class ProductSerializer(serializers.ModelSerializer):
    collection = serializers.PrimaryKeyRelatedField(queryset=ProductCollection.objects.all(), many=False)
    color = serializers.PrimaryKeyRelatedField(queryset=ColorParent.objects.all(), many=False)
    images = ProductImageSerializer(many=True)
    descriptions = ProductDescriptionSerializer(many=True)
    markets = ProductMarketSerializer(many=True)

    class Meta:
        model = Product
        fields = ['id', 'product_code', 'collection', 'color', 'images', 'descriptions', 'markets', 'video', 'status']

    def create(self, validated_data):
        image_data = validated_data.pop('images')
        description_data = validated_data.pop('descriptions')
        market_data = validated_data.pop('markets')

        images = []
        for image in image_data:
            img_obj = ProductImage.objects.create(**image)
            images.append(img_obj)

        descriptions = []
        for description in description_data:
            desc_obj = ProductDescription.objects.create(**description)
            descriptions.append(desc_obj)

        markets = []
        for market in market_data:
            slabs = market.pop('slabs')
            thicknesses = market.pop('thicknesses')
            finish_types = market.pop('finish_types')
            market_obj = ProductMarket.objects.create(**market)
            market_obj.slabs.set(slabs)
            market_obj.thicknesses.set(thicknesses)
            market_obj.finish_types.set(finish_types)
            markets.append(market_obj)

        product = Product.objects.create(**validated_data)
        product.images.set(images)
        product.descriptions.set(descriptions)
        product.markets.set(markets)

        return product

views.py

class ProductView(viewsets.ModelViewSet):
    permission_classes = [permissions.DjangoModelPermissions]
    serializer_class = ProductSerializer
    queryset = Product.objects.all()

目前我只能在 1 个markets 字段内发送 1 个 slabsthicknessesfinish_types。如何为相同的markets 添加另一个slabsthicknessesfinish_types?如果我使用表单数据作为正文,正确的键值对格式是什么? 创建的Product对象:


    "message": "success",
    "data": 
        "id": 60,
        "product_code": "BQ1010",
        "collection": 1,
        "color": 1,
        "images": [
            
                "id": 57,
                "image": "image",
                "default": false
            
        ],
        "descriptions": [
            
                "id": 65,
                "language": 1,
                "description": "new description in english"
            
        ],
        "markets": [
            
                "id": 47,
                "market": 1,
                "name": "White Stone",
                "slabs": [
                    1
                ],
                "thicknesses": [
                    2
                ],
                "finish_types": [
                    1
                ]
            
        ],
        "video": "https://www.youtube.com",
        "status": "Continue"
    

当我尝试像这样添加第二个 slabsthicknesses 时: slabsthicknesses 字段将为空。

 "markets": [
            
                "id": 48,
                "market": 1,
                "name": "White Stone",
                "slabs": [],
                "thicknesses": [],
                "finish_types": [
                    1
                ]
            
        ],

【问题讨论】:

【参考方案1】:

如何在 Django REST Framework 中使用 Postman 表单数据发布嵌套数组?

group_permission[0]permission:share_item

group_permission[0]user_group:1

group_permission[0]key:5

group_permission[0]groups:1

group_permission[0]value:True

【讨论】:

【参考方案2】:

多组 Python

import math
import os
import random
import re
import sys


class Multiset:
    def __init__(self):
        self.item=[]

    def add(self, val):
        # adds one occurrence of val from the multiset, if any
        return self.item.append(val)
        

    def remove(self, val):
        # removes one occurrence of val from the multiset, if any
        if self.item.count(val)!=0:
            return self.item.remove(val)

    def __contains__(self, val):
        # returns True when val is in the multiset, else returns False
        if val in self.item:
            return True
        else:
            return False
    
    def __len__(self):
        # returns the number of elements in the multiset
        return len(self.item)
if __name__ == '__main__':

【讨论】:

以上是关于如何使用 Postman 表单数据在 Django REST Framework 中发布嵌套数组?的主要内容,如果未能解决你的问题,请参考以下文章

通过 urlpatterns 和视图替换 django-postman 中的默认表单

如何使用 Postman 表单数据将 POST 请求发送到 Spring Boot REST API?

如何将数组作为表单数据传递给 Postman

如何从 Django 在前端获取 CSRF 令牌以及如何在 Postman 中使用它

带有 JWT 身份验证实现的 Django GraphQL API 仍然允许来自 Postman 的未经身份验证的请求获取数据。我该如何解决?

多部分/表单数据的 POSTMAN