问题
when I am implementing this code-example on the documentation (I had to implement the create method myself because I have nested objects and inserting them is not supported by default)
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create(**validated_data)
Profile.objects.create(user=user, **profile_data)
return user
https://www.django-rest-framework.org/api-guide/serializers/#writing-create-methods-for-nested-representations
I'm getting this error
create() argument after ** must be a mapping, not list
My implementation of the example on my project is the following :
def create(self, validated_data):
product_data = validated_data.pop('categories')
product = Product.objects.create(**validated_data)
Product.objects.create(product=product, **product_data)
return product
the whole serializers.py file
from rest_framework import serializers
from products_and_categories.models import Product, Category
from django.db import models
class CategorySerializer(serializers.ModelSerializer):
def to_representation(self, obj):
if 'categories' not in self.fields:
self.fields['categories'] = CategorySerializer(obj, many=True)
return super(CategorySerializer, self).to_representation(obj)
class Meta:
model = Category
fields = ("name", 'products', 'categories')
class ProductSerializer(serializers.ModelSerializer):
categories = CategorySerializer(many=True)
class Meta:
model = Product
fields = ("product_code", "name", "quantity", "price", 'categories')
def create(self, validated_data):
product_data = validated_data.pop('categories')
product = Product.objects.create(**validated_data)
Product.objects.create(product=product, **product_data)
return product
my models.py file:
from django.db import models
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=255)
categoriesId = models.ForeignKey('self', related_name='categories',on_delete=models.CASCADE, blank=True, null=True)
class Product(models.Model):
product_code = models.CharField(max_length=255)
name = models.CharField(max_length=255)
price = models.IntegerField()
quantity = models.IntegerField()
categories = models.ManyToManyField(Category, related_name='products')
can anybody help me figure out what's wrong ?
回答1:
You're confusing various names here. You pop the categories
element from validated_data
, and assign it to product_data
; but it is not product data, it is a list of categories.
You then try and create a Product with that data related to an existing product - presumably you meant to create a Category there. But again what you have is a list, so you need to iterate through and create one category per entry.
And finally note that you have a many-to-many relationship between product and category, not a foreign key as in the example, so you can't use that product=product
syntax.
This would be better as:
def create(self, validated_data):
category_data = validated_data.pop('categories')
product = Product.objects.create(**validated_data)
for category in category_data:
product.categories.create(**category)
return product
(Although note that yes, creating nested items is supported by DRF; see the docs on serializer relations.)
来源:https://stackoverflow.com/questions/53418075/create-argument-after-must-be-a-mapping-not-list-django-rest-framework-i