Serializer ForeignKey results in “Expected a dictionary …”












1















My Model:



class Font(ValidateVersionOnSaveMixin, models.Model):
id = models.UUIDField(primary_key=True, editable=True)
name = models.CharField(max_length=100, blank=False, null=False)


class Glyph(ValidateVersionOnSaveMixin, models.Model):
id = models.UUIDField(primary_key=True, editable=True)
unit = models.CharField(max_length=100, blank=False, null=False, unique=True)
font = models.ForeignKey(Font, on_delete=models.CASCADE)


I want to post the following JSON to add a Glyph to an already existing Font (having the fontId as ID) object.



{
fontId: "4a14a055-3c8a-43ba-aab3-221b4244ac73"
id: "40da7a83-a204-4319-9a04-b0a544bf4440"
unit: "aaa"
}


As there is a mismatch between the ForeignKey Field font and the JSON propertyfontId I am adding source='font' in my Serializer:



class FontSerializer(serializers.ModelSerializer):
class Meta:
model = Font
fields = ('id', 'name')


class GlyphSerializer(serializers.ModelSerializer):
fontId = FontSerializer(source='font')
class Meta:
model = Glyph
fields = ('id', 'unit', 'fontId' )


But the result is an BAD REQUEST Error:



{"fontId":{"non_field_errors":["Invalid data. Expected a dictionary, but got str."]}}




Update



The following Serializer gave me the result I was looking for.



class GlyphSerializer(serializers.ModelSerializer):
fontId = serializers.PrimaryKeyRelatedField(
queryset=Font.objects.all(),
required=True,
source='font',
write_only=False
)
class Meta:
model = Glyph
fields = ('id', 'unit', 'version', 'fontId')









share|improve this question

























  • Related - stackoverflow.com/questions/28010663/…

    – shad0w_wa1k3r
    May 2 '17 at 16:32











  • Possible duplicate of SerializerClass field on Serializer save from primary key

    – shad0w_wa1k3r
    May 2 '17 at 16:33
















1















My Model:



class Font(ValidateVersionOnSaveMixin, models.Model):
id = models.UUIDField(primary_key=True, editable=True)
name = models.CharField(max_length=100, blank=False, null=False)


class Glyph(ValidateVersionOnSaveMixin, models.Model):
id = models.UUIDField(primary_key=True, editable=True)
unit = models.CharField(max_length=100, blank=False, null=False, unique=True)
font = models.ForeignKey(Font, on_delete=models.CASCADE)


I want to post the following JSON to add a Glyph to an already existing Font (having the fontId as ID) object.



{
fontId: "4a14a055-3c8a-43ba-aab3-221b4244ac73"
id: "40da7a83-a204-4319-9a04-b0a544bf4440"
unit: "aaa"
}


As there is a mismatch between the ForeignKey Field font and the JSON propertyfontId I am adding source='font' in my Serializer:



class FontSerializer(serializers.ModelSerializer):
class Meta:
model = Font
fields = ('id', 'name')


class GlyphSerializer(serializers.ModelSerializer):
fontId = FontSerializer(source='font')
class Meta:
model = Glyph
fields = ('id', 'unit', 'fontId' )


But the result is an BAD REQUEST Error:



{"fontId":{"non_field_errors":["Invalid data. Expected a dictionary, but got str."]}}




Update



The following Serializer gave me the result I was looking for.



class GlyphSerializer(serializers.ModelSerializer):
fontId = serializers.PrimaryKeyRelatedField(
queryset=Font.objects.all(),
required=True,
source='font',
write_only=False
)
class Meta:
model = Glyph
fields = ('id', 'unit', 'version', 'fontId')









share|improve this question

























  • Related - stackoverflow.com/questions/28010663/…

    – shad0w_wa1k3r
    May 2 '17 at 16:32











  • Possible duplicate of SerializerClass field on Serializer save from primary key

    – shad0w_wa1k3r
    May 2 '17 at 16:33














1












1








1


0






My Model:



class Font(ValidateVersionOnSaveMixin, models.Model):
id = models.UUIDField(primary_key=True, editable=True)
name = models.CharField(max_length=100, blank=False, null=False)


class Glyph(ValidateVersionOnSaveMixin, models.Model):
id = models.UUIDField(primary_key=True, editable=True)
unit = models.CharField(max_length=100, blank=False, null=False, unique=True)
font = models.ForeignKey(Font, on_delete=models.CASCADE)


I want to post the following JSON to add a Glyph to an already existing Font (having the fontId as ID) object.



{
fontId: "4a14a055-3c8a-43ba-aab3-221b4244ac73"
id: "40da7a83-a204-4319-9a04-b0a544bf4440"
unit: "aaa"
}


As there is a mismatch between the ForeignKey Field font and the JSON propertyfontId I am adding source='font' in my Serializer:



class FontSerializer(serializers.ModelSerializer):
class Meta:
model = Font
fields = ('id', 'name')


class GlyphSerializer(serializers.ModelSerializer):
fontId = FontSerializer(source='font')
class Meta:
model = Glyph
fields = ('id', 'unit', 'fontId' )


But the result is an BAD REQUEST Error:



{"fontId":{"non_field_errors":["Invalid data. Expected a dictionary, but got str."]}}




Update



The following Serializer gave me the result I was looking for.



class GlyphSerializer(serializers.ModelSerializer):
fontId = serializers.PrimaryKeyRelatedField(
queryset=Font.objects.all(),
required=True,
source='font',
write_only=False
)
class Meta:
model = Glyph
fields = ('id', 'unit', 'version', 'fontId')









share|improve this question
















My Model:



class Font(ValidateVersionOnSaveMixin, models.Model):
id = models.UUIDField(primary_key=True, editable=True)
name = models.CharField(max_length=100, blank=False, null=False)


class Glyph(ValidateVersionOnSaveMixin, models.Model):
id = models.UUIDField(primary_key=True, editable=True)
unit = models.CharField(max_length=100, blank=False, null=False, unique=True)
font = models.ForeignKey(Font, on_delete=models.CASCADE)


I want to post the following JSON to add a Glyph to an already existing Font (having the fontId as ID) object.



{
fontId: "4a14a055-3c8a-43ba-aab3-221b4244ac73"
id: "40da7a83-a204-4319-9a04-b0a544bf4440"
unit: "aaa"
}


As there is a mismatch between the ForeignKey Field font and the JSON propertyfontId I am adding source='font' in my Serializer:



class FontSerializer(serializers.ModelSerializer):
class Meta:
model = Font
fields = ('id', 'name')


class GlyphSerializer(serializers.ModelSerializer):
fontId = FontSerializer(source='font')
class Meta:
model = Glyph
fields = ('id', 'unit', 'fontId' )


But the result is an BAD REQUEST Error:



{"fontId":{"non_field_errors":["Invalid data. Expected a dictionary, but got str."]}}




Update



The following Serializer gave me the result I was looking for.



class GlyphSerializer(serializers.ModelSerializer):
fontId = serializers.PrimaryKeyRelatedField(
queryset=Font.objects.all(),
required=True,
source='font',
write_only=False
)
class Meta:
model = Glyph
fields = ('id', 'unit', 'version', 'fontId')






django django-rest-framework






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 '16 at 8:50







tobltobs

















asked Nov 7 '16 at 21:51









tobltobstobltobs

1,5861525




1,5861525













  • Related - stackoverflow.com/questions/28010663/…

    – shad0w_wa1k3r
    May 2 '17 at 16:32











  • Possible duplicate of SerializerClass field on Serializer save from primary key

    – shad0w_wa1k3r
    May 2 '17 at 16:33



















  • Related - stackoverflow.com/questions/28010663/…

    – shad0w_wa1k3r
    May 2 '17 at 16:32











  • Possible duplicate of SerializerClass field on Serializer save from primary key

    – shad0w_wa1k3r
    May 2 '17 at 16:33

















Related - stackoverflow.com/questions/28010663/…

– shad0w_wa1k3r
May 2 '17 at 16:32





Related - stackoverflow.com/questions/28010663/…

– shad0w_wa1k3r
May 2 '17 at 16:32













Possible duplicate of SerializerClass field on Serializer save from primary key

– shad0w_wa1k3r
May 2 '17 at 16:33





Possible duplicate of SerializerClass field on Serializer save from primary key

– shad0w_wa1k3r
May 2 '17 at 16:33












3 Answers
3






active

oldest

votes


















1














You have defined fontId as being a serialized object (FontSerializer). But that serializer in turn is defined as having both an id and a name. Where as your json dictionary is posting only an id. You would have to change that to a dictionary that contains both an id and a name



{
fontId: {id: "4a14a055-3c8a-43ba-aab3-221b4244ac73",name: "some name" },
id: "40da7a83-a204-4319-9a04-b0a544bf4440"
unit: "aaa"
}





share|improve this answer
























  • The font already exists. I want to add a glyph to this font with my JSON. Is there a way to do this without changing the JSON?

    – tobltobs
    Nov 7 '16 at 23:16











  • sorry for delay. Missed the notification. Did you manage to sort this out or do you still need this input form me?

    – e4c5
    Nov 23 '16 at 12:33











  • Thanks for asking back. I sorted it out, see the Update to my question.

    – tobltobs
    Nov 23 '16 at 13:12



















0














The reason you are getting this error is that during deserialization process, DRF calls .is_valid(raise_exception=True) before you can call serializer.save(validated_data). And non_field_errors lists any general validation errors during this process. In your GlyphSerializer, your FontSerializer is a nested serializer, which correlates to a Python dictionary. So it will raise an error like you encountered for any non-dictionary data types.



You could create a subclass of GlyphSerializer called GlyphCreateSerializer



class FontSerializer(serializers.ModelSerializer):
class Meta:
model = Font
fields = ('id', 'name')


class GlyphSerializer(serializers.ModelSerializer):
fontId = FontSerializer(source='font')
class Meta:
model = Glyph
fields = ('id', 'unit', 'fontId' )

class GlyphCreateSerializer(GlyphSerializer):
fontId = serializers.CharField()


And you can use GlyphCreateSerializer for the POST request on your Viewset.






share|improve this answer































    0














    You can user model_to_dict method as bellow:



    from django.forms.models import model_to_dict
    model_to_dict(obj)





    share|improve this answer























      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%2f40475309%2fserializer-foreignkey-results-in-expected-a-dictionary%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      You have defined fontId as being a serialized object (FontSerializer). But that serializer in turn is defined as having both an id and a name. Where as your json dictionary is posting only an id. You would have to change that to a dictionary that contains both an id and a name



      {
      fontId: {id: "4a14a055-3c8a-43ba-aab3-221b4244ac73",name: "some name" },
      id: "40da7a83-a204-4319-9a04-b0a544bf4440"
      unit: "aaa"
      }





      share|improve this answer
























      • The font already exists. I want to add a glyph to this font with my JSON. Is there a way to do this without changing the JSON?

        – tobltobs
        Nov 7 '16 at 23:16











      • sorry for delay. Missed the notification. Did you manage to sort this out or do you still need this input form me?

        – e4c5
        Nov 23 '16 at 12:33











      • Thanks for asking back. I sorted it out, see the Update to my question.

        – tobltobs
        Nov 23 '16 at 13:12
















      1














      You have defined fontId as being a serialized object (FontSerializer). But that serializer in turn is defined as having both an id and a name. Where as your json dictionary is posting only an id. You would have to change that to a dictionary that contains both an id and a name



      {
      fontId: {id: "4a14a055-3c8a-43ba-aab3-221b4244ac73",name: "some name" },
      id: "40da7a83-a204-4319-9a04-b0a544bf4440"
      unit: "aaa"
      }





      share|improve this answer
























      • The font already exists. I want to add a glyph to this font with my JSON. Is there a way to do this without changing the JSON?

        – tobltobs
        Nov 7 '16 at 23:16











      • sorry for delay. Missed the notification. Did you manage to sort this out or do you still need this input form me?

        – e4c5
        Nov 23 '16 at 12:33











      • Thanks for asking back. I sorted it out, see the Update to my question.

        – tobltobs
        Nov 23 '16 at 13:12














      1












      1








      1







      You have defined fontId as being a serialized object (FontSerializer). But that serializer in turn is defined as having both an id and a name. Where as your json dictionary is posting only an id. You would have to change that to a dictionary that contains both an id and a name



      {
      fontId: {id: "4a14a055-3c8a-43ba-aab3-221b4244ac73",name: "some name" },
      id: "40da7a83-a204-4319-9a04-b0a544bf4440"
      unit: "aaa"
      }





      share|improve this answer













      You have defined fontId as being a serialized object (FontSerializer). But that serializer in turn is defined as having both an id and a name. Where as your json dictionary is posting only an id. You would have to change that to a dictionary that contains both an id and a name



      {
      fontId: {id: "4a14a055-3c8a-43ba-aab3-221b4244ac73",name: "some name" },
      id: "40da7a83-a204-4319-9a04-b0a544bf4440"
      unit: "aaa"
      }






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Nov 7 '16 at 23:05









      e4c5e4c5

      40.8k85187




      40.8k85187













      • The font already exists. I want to add a glyph to this font with my JSON. Is there a way to do this without changing the JSON?

        – tobltobs
        Nov 7 '16 at 23:16











      • sorry for delay. Missed the notification. Did you manage to sort this out or do you still need this input form me?

        – e4c5
        Nov 23 '16 at 12:33











      • Thanks for asking back. I sorted it out, see the Update to my question.

        – tobltobs
        Nov 23 '16 at 13:12



















      • The font already exists. I want to add a glyph to this font with my JSON. Is there a way to do this without changing the JSON?

        – tobltobs
        Nov 7 '16 at 23:16











      • sorry for delay. Missed the notification. Did you manage to sort this out or do you still need this input form me?

        – e4c5
        Nov 23 '16 at 12:33











      • Thanks for asking back. I sorted it out, see the Update to my question.

        – tobltobs
        Nov 23 '16 at 13:12

















      The font already exists. I want to add a glyph to this font with my JSON. Is there a way to do this without changing the JSON?

      – tobltobs
      Nov 7 '16 at 23:16





      The font already exists. I want to add a glyph to this font with my JSON. Is there a way to do this without changing the JSON?

      – tobltobs
      Nov 7 '16 at 23:16













      sorry for delay. Missed the notification. Did you manage to sort this out or do you still need this input form me?

      – e4c5
      Nov 23 '16 at 12:33





      sorry for delay. Missed the notification. Did you manage to sort this out or do you still need this input form me?

      – e4c5
      Nov 23 '16 at 12:33













      Thanks for asking back. I sorted it out, see the Update to my question.

      – tobltobs
      Nov 23 '16 at 13:12





      Thanks for asking back. I sorted it out, see the Update to my question.

      – tobltobs
      Nov 23 '16 at 13:12













      0














      The reason you are getting this error is that during deserialization process, DRF calls .is_valid(raise_exception=True) before you can call serializer.save(validated_data). And non_field_errors lists any general validation errors during this process. In your GlyphSerializer, your FontSerializer is a nested serializer, which correlates to a Python dictionary. So it will raise an error like you encountered for any non-dictionary data types.



      You could create a subclass of GlyphSerializer called GlyphCreateSerializer



      class FontSerializer(serializers.ModelSerializer):
      class Meta:
      model = Font
      fields = ('id', 'name')


      class GlyphSerializer(serializers.ModelSerializer):
      fontId = FontSerializer(source='font')
      class Meta:
      model = Glyph
      fields = ('id', 'unit', 'fontId' )

      class GlyphCreateSerializer(GlyphSerializer):
      fontId = serializers.CharField()


      And you can use GlyphCreateSerializer for the POST request on your Viewset.






      share|improve this answer




























        0














        The reason you are getting this error is that during deserialization process, DRF calls .is_valid(raise_exception=True) before you can call serializer.save(validated_data). And non_field_errors lists any general validation errors during this process. In your GlyphSerializer, your FontSerializer is a nested serializer, which correlates to a Python dictionary. So it will raise an error like you encountered for any non-dictionary data types.



        You could create a subclass of GlyphSerializer called GlyphCreateSerializer



        class FontSerializer(serializers.ModelSerializer):
        class Meta:
        model = Font
        fields = ('id', 'name')


        class GlyphSerializer(serializers.ModelSerializer):
        fontId = FontSerializer(source='font')
        class Meta:
        model = Glyph
        fields = ('id', 'unit', 'fontId' )

        class GlyphCreateSerializer(GlyphSerializer):
        fontId = serializers.CharField()


        And you can use GlyphCreateSerializer for the POST request on your Viewset.






        share|improve this answer


























          0












          0








          0







          The reason you are getting this error is that during deserialization process, DRF calls .is_valid(raise_exception=True) before you can call serializer.save(validated_data). And non_field_errors lists any general validation errors during this process. In your GlyphSerializer, your FontSerializer is a nested serializer, which correlates to a Python dictionary. So it will raise an error like you encountered for any non-dictionary data types.



          You could create a subclass of GlyphSerializer called GlyphCreateSerializer



          class FontSerializer(serializers.ModelSerializer):
          class Meta:
          model = Font
          fields = ('id', 'name')


          class GlyphSerializer(serializers.ModelSerializer):
          fontId = FontSerializer(source='font')
          class Meta:
          model = Glyph
          fields = ('id', 'unit', 'fontId' )

          class GlyphCreateSerializer(GlyphSerializer):
          fontId = serializers.CharField()


          And you can use GlyphCreateSerializer for the POST request on your Viewset.






          share|improve this answer













          The reason you are getting this error is that during deserialization process, DRF calls .is_valid(raise_exception=True) before you can call serializer.save(validated_data). And non_field_errors lists any general validation errors during this process. In your GlyphSerializer, your FontSerializer is a nested serializer, which correlates to a Python dictionary. So it will raise an error like you encountered for any non-dictionary data types.



          You could create a subclass of GlyphSerializer called GlyphCreateSerializer



          class FontSerializer(serializers.ModelSerializer):
          class Meta:
          model = Font
          fields = ('id', 'name')


          class GlyphSerializer(serializers.ModelSerializer):
          fontId = FontSerializer(source='font')
          class Meta:
          model = Glyph
          fields = ('id', 'unit', 'fontId' )

          class GlyphCreateSerializer(GlyphSerializer):
          fontId = serializers.CharField()


          And you can use GlyphCreateSerializer for the POST request on your Viewset.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 1 '17 at 21:47









          PatDuJourPatDuJour

          602517




          602517























              0














              You can user model_to_dict method as bellow:



              from django.forms.models import model_to_dict
              model_to_dict(obj)





              share|improve this answer




























                0














                You can user model_to_dict method as bellow:



                from django.forms.models import model_to_dict
                model_to_dict(obj)





                share|improve this answer


























                  0












                  0








                  0







                  You can user model_to_dict method as bellow:



                  from django.forms.models import model_to_dict
                  model_to_dict(obj)





                  share|improve this answer













                  You can user model_to_dict method as bellow:



                  from django.forms.models import model_to_dict
                  model_to_dict(obj)






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 17 '18 at 20:26









                  Juba FOURALIJuba FOURALI

                  193




                  193






























                      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%2f40475309%2fserializer-foreignkey-results-in-expected-a-dictionary%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

                      Guess what letter conforming each word

                      Port of Spain

                      Run scheduled task as local user group (not BUILTIN)