如何使用 django Rest api 上传多个文件?

2024-02-17

我正在尝试使用 django Rest api 上传多个图像。我遵循以下approach https://stackoverflow.com/questions/39645410/how-to-upload-multiple-files-in-django-rest-framework。但是,当我选择一个或多个文件并尝试将它们作为表单数据发送到服务器时,我收到以下错误消息:

AttributeError at /api/photo/ 'bytes' object has no attribute 'name'

Model:

class Photo(models.Model):
    image = models.ImageField(upload_to='audio_stories/')

序列化器:

class FileListSerializer ( serializers.Serializer ) :
    image = serializers.ListField(
                child=serializers.FileField( max_length=100000,
                                         allow_empty_file=False,
                                        use_url=False )
                                )
    def create(self, validated_data):
        image=validated_data.pop('image')
        for img in image:
            photo=Photo.objects.create(image=img,**validated_data)
        return photo

View:

class PhotoViewSet(viewsets.ModelViewSet):
    serializer_class = FileListSerializer
    parser_classes = (MultiPartParser, FormParser,)
    queryset=Photo.objects.all()

URL

router.register('api/photo', PhotoViewSet, 'photocreate')

我不知道如何处理该错误,因为我的代码中没有任何与“名称”相关的内容?


错误似乎出在序列化器中。我必须设置use_url=True.

序列化器:

class FileListSerializer ( serializers.Serializer ) :
    image = serializers.ListField(
                child=serializers.FileField( max_length=100000,
                                         allow_empty_file=False,
                                        use_url=True )
                                )
    def create(self, validated_data):
        image=validated_data.pop('image')
        for img in image:
            photo=Photo.objects.create(image=img,**validated_data)
        return photo

扩展答案

上面的答案有效,但会产生一个大的空数组。 为了使代码正常工作,我必须将 Story 和 Story_Media 中的两个模型分开。 Story Media 的每个实例都包含一个图像并为 Story 提供 FK。

class Story (models.Model):
    title = models.CharField(max_length=100, blank=True)
    description = models.TextField(blank=True)
    date_posted = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return f'{self.id} Story'

class Story_Media (models.Model):
    story = models.ForeignKey(Story,on_delete=models.CASCADE, null=True, related_name = 'story_media', related_query_name = 'story_media')
    file = models.FileField(upload_to='story_media/',  null=True, validators=[validate_file_extension_image])
    isTitlePicture = models.BooleanField(blank=False, null=True)

    def __str__(self):
        return f'{self.id} Media'

在我的序列化器中,为传入数据中包含的每个图像创建一个新的 Sotry_Media 实例。就我而言,即使没有上传图像,也有必要创建一个故事,因此包括两个条件。

# Story  Serializer_Media_Serializer
class Story_Media_Serializer (serializers.ModelSerializer):

    class Meta:
        model = Story_Media
        fields =  ('id','isTitlePicture', 'file',)


# Story  Serializer
class StoryCreateUpdateSerializer (serializers.ModelSerializer):
    story_media = Story_Media_Serializer(many=True, required = False)


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

    def create(self, validated_data):
        current_user = self.context["request"].user

        # Story  contains images
        if 'story_media' in validated_data:
            story_media = validated_data.pop('story_media')
            story_instance = Story.objects.create(author=current_user, **validated_data)
            for img in story_media:
                Story_Media.objects.create(**img, story=story_instance)
            return story_instance

        # Story  is not containing images
        if 'story_media'not in validated_data:
            story_instance = Story.objects.create(author=current_user, **validated_data)
            return story_instance

class StoryCreateUpdateViewSet(viewsets.ModelViewSet):
    serializer_class = StoryCreateUpdateSerializer

    http_method_names = ['post','delete','put','patch', 'head']

    queryset = Story.objects.all()

    permission_classes = [
        permissions.IsAuthenticated, PostOwnerPermssion
    ]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 django Rest api 上传多个文件? 的相关文章

随机推荐