4

I have a nested writable serializer with array fields. I need to test it with form-data because one of the field type is ImageField. When I changed the ImageField into CharField it worked fine if I posted it with raw JSON format.
My simplified 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()

For now I can only send 1 slabs, thicknesses, and finish_types each within 1 markets field. How to add another slabs, thicknesses, and finish_types for the same markets? What's the correct key-value pair format if I use form-data as Body?
enter image description here
The created Product object:

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

When I try to add the second slabs and thicknesses like this: enter image description here
The slabs and thicknesses fields will be empty.

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

3 Answers 3

3

How to post nested arrays in Django REST Framework with Postman form-data?

enter image description here

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
Sign up to request clarification or add additional context in comments.

Comments

1

As of 04-08-2023: Now you can give nested values with only dot notation. No need for [0]. example:

___________________________________________________
Column Key                  | Column Value
---------------------------------------------------
group_permission.permission | share_item
group_permission.user_group | 1
group_permission.key        | 5
group_permission.groups     | 1
group_permission.value      | True
---------------------------------------------------

Note: For Django Users you need to set a parser class for your views.
eg:
parser_classes = [MultiPartParser, FormParser]

Comments

-1

Multiset 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__':

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.