create() argument after ** must be a mapping, not list, Django REST Framework (implementing my own create...












0















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 ?










share|improve this question



























    0















    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 ?










    share|improve this question

























      0












      0








      0








      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 ?










      share|improve this question














      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 ?







      python django django-rest-framework






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 21 '18 at 18:02









      Amr S.Amr S.

      305




      305
























          1 Answer
          1






          active

          oldest

          votes


















          0














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






          share|improve this answer


























          • Thanks so much, although after trying your way , I get an error saying Direct assignment to the reverse side of a many-to-many set is prohibited. Use products.set() instead. and when I used product.categories.set(**category_data) I got set() got an unexpected keyword argument 'name'

            – Amr S.
            Nov 21 '18 at 18:29













          • any idea what that is ?

            – Amr S.
            Nov 21 '18 at 18:30











          • This code wouldn't give that error. Can you update your question with the exact code you used?

            – Daniel Roseman
            Nov 21 '18 at 18:38











          • you meant category by category_data in product.categories.create(**category_data), right ? because otherwise it gives the create() argument after ** must be a mapping, not list error again

            – Amr S.
            Nov 21 '18 at 18:43











          • Yes, sorry, you're right.

            – Daniel Roseman
            Nov 21 '18 at 18:44











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418075%2fcreate-argument-after-must-be-a-mapping-not-list-django-rest-framework-i%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














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






          share|improve this answer


























          • Thanks so much, although after trying your way , I get an error saying Direct assignment to the reverse side of a many-to-many set is prohibited. Use products.set() instead. and when I used product.categories.set(**category_data) I got set() got an unexpected keyword argument 'name'

            – Amr S.
            Nov 21 '18 at 18:29













          • any idea what that is ?

            – Amr S.
            Nov 21 '18 at 18:30











          • This code wouldn't give that error. Can you update your question with the exact code you used?

            – Daniel Roseman
            Nov 21 '18 at 18:38











          • you meant category by category_data in product.categories.create(**category_data), right ? because otherwise it gives the create() argument after ** must be a mapping, not list error again

            – Amr S.
            Nov 21 '18 at 18:43











          • Yes, sorry, you're right.

            – Daniel Roseman
            Nov 21 '18 at 18:44
















          0














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






          share|improve this answer


























          • Thanks so much, although after trying your way , I get an error saying Direct assignment to the reverse side of a many-to-many set is prohibited. Use products.set() instead. and when I used product.categories.set(**category_data) I got set() got an unexpected keyword argument 'name'

            – Amr S.
            Nov 21 '18 at 18:29













          • any idea what that is ?

            – Amr S.
            Nov 21 '18 at 18:30











          • This code wouldn't give that error. Can you update your question with the exact code you used?

            – Daniel Roseman
            Nov 21 '18 at 18:38











          • you meant category by category_data in product.categories.create(**category_data), right ? because otherwise it gives the create() argument after ** must be a mapping, not list error again

            – Amr S.
            Nov 21 '18 at 18:43











          • Yes, sorry, you're right.

            – Daniel Roseman
            Nov 21 '18 at 18:44














          0












          0








          0







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






          share|improve this answer















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







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 21 '18 at 18:44

























          answered Nov 21 '18 at 18:10









          Daniel RosemanDaniel Roseman

          446k41577634




          446k41577634













          • Thanks so much, although after trying your way , I get an error saying Direct assignment to the reverse side of a many-to-many set is prohibited. Use products.set() instead. and when I used product.categories.set(**category_data) I got set() got an unexpected keyword argument 'name'

            – Amr S.
            Nov 21 '18 at 18:29













          • any idea what that is ?

            – Amr S.
            Nov 21 '18 at 18:30











          • This code wouldn't give that error. Can you update your question with the exact code you used?

            – Daniel Roseman
            Nov 21 '18 at 18:38











          • you meant category by category_data in product.categories.create(**category_data), right ? because otherwise it gives the create() argument after ** must be a mapping, not list error again

            – Amr S.
            Nov 21 '18 at 18:43











          • Yes, sorry, you're right.

            – Daniel Roseman
            Nov 21 '18 at 18:44



















          • Thanks so much, although after trying your way , I get an error saying Direct assignment to the reverse side of a many-to-many set is prohibited. Use products.set() instead. and when I used product.categories.set(**category_data) I got set() got an unexpected keyword argument 'name'

            – Amr S.
            Nov 21 '18 at 18:29













          • any idea what that is ?

            – Amr S.
            Nov 21 '18 at 18:30











          • This code wouldn't give that error. Can you update your question with the exact code you used?

            – Daniel Roseman
            Nov 21 '18 at 18:38











          • you meant category by category_data in product.categories.create(**category_data), right ? because otherwise it gives the create() argument after ** must be a mapping, not list error again

            – Amr S.
            Nov 21 '18 at 18:43











          • Yes, sorry, you're right.

            – Daniel Roseman
            Nov 21 '18 at 18:44

















          Thanks so much, although after trying your way , I get an error saying Direct assignment to the reverse side of a many-to-many set is prohibited. Use products.set() instead. and when I used product.categories.set(**category_data) I got set() got an unexpected keyword argument 'name'

          – Amr S.
          Nov 21 '18 at 18:29







          Thanks so much, although after trying your way , I get an error saying Direct assignment to the reverse side of a many-to-many set is prohibited. Use products.set() instead. and when I used product.categories.set(**category_data) I got set() got an unexpected keyword argument 'name'

          – Amr S.
          Nov 21 '18 at 18:29















          any idea what that is ?

          – Amr S.
          Nov 21 '18 at 18:30





          any idea what that is ?

          – Amr S.
          Nov 21 '18 at 18:30













          This code wouldn't give that error. Can you update your question with the exact code you used?

          – Daniel Roseman
          Nov 21 '18 at 18:38





          This code wouldn't give that error. Can you update your question with the exact code you used?

          – Daniel Roseman
          Nov 21 '18 at 18:38













          you meant category by category_data in product.categories.create(**category_data), right ? because otherwise it gives the create() argument after ** must be a mapping, not list error again

          – Amr S.
          Nov 21 '18 at 18:43





          you meant category by category_data in product.categories.create(**category_data), right ? because otherwise it gives the create() argument after ** must be a mapping, not list error again

          – Amr S.
          Nov 21 '18 at 18:43













          Yes, sorry, you're right.

          – Daniel Roseman
          Nov 21 '18 at 18:44





          Yes, sorry, you're right.

          – Daniel Roseman
          Nov 21 '18 at 18:44


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418075%2fcreate-argument-after-must-be-a-mapping-not-list-django-rest-framework-i%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Ottavio Pratesi

          Tricia Helfer

          15 giugno