2016-11-07 52 views
0

我的模型:串行ForeignKey的结果“预期字典......”

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) 

我要发布以下JSON的雕文添加到已经存在的字体(具有fontId作为ID)对象。

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

由于存在ForeignKey的领域font和JSON财产fontId我加入我的串行source='font'之间的不匹配:

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

但结果却是一个错误请求错误:

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

更新

下面的Serializer给了我想要的结果。

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') 
+0

相关 - https://stackoverflow.com/questions/28010663/serializerclass-field-on-serializer-save-from-primary-key –

+0

[SerializerClass字段串行器保存从主键]可能的副本(http:///stackoverflow.com/questions/28010663/serializerclass-field-on-serializer-save-from-primary-key) –

回答

1

您已定义fontId为序列化对象(FontSerializer)。但是,该序列化器又被定义为同时拥有一个id和一个名称。你的json字典只发布一个id。你将不得不改变,要同时包含一个ID和一个名字的字典

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

字体已存在。我想用我的JSON为这个字体添加一个字形。有没有办法做到这一点,而不改变JSON? – tobltobs

+0

抱歉延误。错过了通知。你有没有设法解决这个问题,或者你还需要这种输入吗? – e4c5

+0

谢谢你回复。我把它整理出来,看看我的问题更新。 – tobltobs

0

您收到此错误的原因是,在反序列化过程中,DRF调用.is_valid(raise_exception=True)你可以打电话serializer.save(validated_data)之前。 non_field_errors列出了此过程中的任何常规验证错误。在您的GlyphSerializer中,您的FontSerializer是嵌套的序列化程序,它与Python字典相关。所以它会引发你遇到的任何非字典数据类型的错误。

您可以创建的GlyphSerializer一个子类,称为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() 

你也可以使用GlyphCreateSerializer在您的视图集POST请求。