繁体   English   中英

如何通过邮递员将发布请求发送到 django-rest-framework 中的嵌套可写序列化程序?

[英]How to send a post request via postman to nested writable serializer in django-rest-framework?

我真的很难以正确的形式将我的数据与邮递员发送到我的 Django 后端。 我遵循了 Django 文档中关于可写嵌套 Seralizer 的方法,并将其调整为适合我的情况。 如果我通过 shell 将数据传递给我的序列化程序,一切正常,我可以创建两个对象实例StoryFile 但是,如果我尝试对Got AttributeError when attempting to get a value for field 'file' on serializer 'StoryCreateUpdateSerializer'. The serializer field might be named incorrectly and not match any attribute or key on the 'Story' instance. Original exception text was: 'Story' object has no attribute 'file'.执行相同操作,则它不会成功并收到以下错误消息: Got AttributeError when attempting to get a value for field 'file' on serializer 'StoryCreateUpdateSerializer'. The serializer field might be named incorrectly and not match any attribute or key on the 'Story' instance. Original exception text was: 'Story' object has no attribute 'file'.出现了Got AttributeError when attempting to get a value for field 'file' on serializer 'StoryCreateUpdateSerializer'. The serializer field might be named incorrectly and not match any attribute or key on the 'Story' instance. Original exception text was: 'Story' object has no attribute 'file'. Got AttributeError when attempting to get a value for field 'file' on serializer 'StoryCreateUpdateSerializer'. The serializer field might be named incorrectly and not match any attribute or key on the 'Story' instance. Original exception text was: 'Story' object has no attribute 'file'.

通过 Shell 成功请求:

>>> data = {
    'title': 'HALLLO',
    'file': [
        {'content': 'Public Service Announcement'},
        {'content': 'Public Service Announcement'},
        {'content': 'Public Service Announcement'},
    ],
}
>>> serializer = StoryCreateUpdateSerializer(data=data)
>>> serializer.is_valid()
True
>>> serializer.save()

通过邮递员请求不成功。 标题:内容类型:应用程序/json。 身体:未加工

{
    "title": "Test",
    "file": [
        {
            "content": "Hallo"
        }
    ]
}

我的模型和序列化器

#MODELS
class Story (models.Model):
    title = models.CharField(max_length=100,blank=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)

class File(models.Model):
    story = models.ForeignKey(Story,on_delete=models.CASCADE, null=True)
    content = models.TextField(blank=False, null=True)
#SERIALIZER
class TestFileSerializer (serializers.ModelSerializer):

    class Meta:
        model = File
        fields =  ('content',)

class StoryCreateUpdateSerializer (serializers.ModelSerializer):
    file = TestFileSerializer(many=True)

    class Meta:
        model = Story
        fields =  ('title','file')

    def create(self, validated_data):
        current_user = self.context["request"].user
        title = validated_data.pop('title')
        file = validated_data.pop('file')
        story_instance = Story.objects.create(author=current_user, title=title)

        for file_data in file:
            File.objects.create(**file_data, story=story_instance)
        return story_instance
#VIEW
class StoryCreateUpdateViewSet(viewsets.ModelViewSet):
    serializer_class = StoryCreateUpdateSerializer

    queryset = Story.objects.all()

我很高兴得到任何澄清。 因为我的想法不多了。

File模型的 ForeignKey 字段中,默认related_namerelated_query_name属性是'file_set'不是'file'

因此,您应该对代码进行以下更改之一:


方法一:
File模型中,将related_namerelated_query_name属性添加到 ForeignKey 字段,其值为'file'

story = models.ForeignKey(
    Story,
    on_delete=models.CASCADE,
    null=True,
    related_name = 'file',
    related_query_name = 'file'
)

方法二:
StoryCreateUpdateSerializer'file'字段更改为'file_set'

class StoryCreateUpdateSerializer (serializers.ModelSerializer):
    file_set = TestFileSerializer(many=True)

    class Meta:
        model = Story
        fields =  ('title','file_set')

    def create(self, validated_data):
        current_user = self.context["request"].user
        title = validated_data.pop('title')
        file = validated_data.pop('file')
        story_instance = Story.objects.create(author=current_user, title=title)

        for file_data in file:
            File.objects.create(**file_data, story=story_instance)
        return story_instance

在此方法中,您还必须更改请求正文属性并将“file”替换为“file_set”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM