Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用django rest api上载多个文件?_Python_Django_Django Rest Framework - Fatal编程技术网

Python 如何使用django rest api上载多个文件?

Python 如何使用django rest api上载多个文件?,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在尝试使用django rest api上载多个图像。我遵循了以下几点。但是,当我选择一个或多个文件并尝试将其作为表单数据发送到服务器时,会收到以下错误消息: AttributeError at/api/photo/'bytes'对象没有属性'name' 型号: class Photo(models.Model): image = models.ImageField(upload_to='audio_stories/') class FileListSerializer ( ser

我正在尝试使用django rest api上载多个图像。我遵循了以下几点。但是,当我选择一个或多个文件并尝试将其作为表单数据发送到服务器时,会收到以下错误消息:

AttributeError at/api/photo/'bytes'对象没有属性'name'

型号:

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

class PhotoViewSet(viewsets.ModelViewSet):
    serializer_class = FileListSerializer
    parser_classes = (MultiPartParser, FormParser,)
    queryset=Photo.objects.all()
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

序列化程序:

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

class PhotoViewSet(viewsets.ModelViewSet):
    serializer_class = FileListSerializer
    parser_classes = (MultiPartParser, FormParser,)
    queryset=Photo.objects.all()
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

查看:

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

class PhotoViewSet(viewsets.ModelViewSet):
    serializer_class = FileListSerializer
    parser_classes = (MultiPartParser, FormParser,)
    queryset=Photo.objects.all()
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

URL

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

<>我不知道该如何处理这个错误,因为我的代码中没有任何与“名称”有关的东西。

也许你应该考虑像我为我工作的那个执行< /P> 型号

class Photo(models.Model):
    title = models.CharField(max_length=255, blank=True)
    image = models.ImageField(upload_to='hotel_photos')
    hotel = models.ForeignKey(
        Hotels, on_delete=models.CASCADE, null=True, blank=True,)

    class Meta:
        verbose_name_plural = 'Photos'

    def __str__(self):
        """Prints the name of the Photo"""
        return f'{self.hotel} photos'
序列化程序

class PhotoSerializer(ModelSerializer):
    class Meta:
        model = Photo
        fields = (
            "image",
            "hotel",
        )
辅助功能

def modify_input_for_multiple_files(hotel, image):
    dict = {}
    dict['hotel'] = hotel
    dict['image'] = image
    return dict
视图.py

class PhotoUploadView(ListCreateAPIView):
    """
    This API view handles multiple images upload form
    It will also display images for specific hotel
    """
    parser_classes = (MultiPartParser, FormParser)
    # http_method_names = ['get', 'post', 'head']

    def get(self, request):
        all_images = Photo.objects.all()
        permission_classes = (IsAdminOrOwner,)
        serializer_class = PhotoSerializer(all_images, many=True)
        return JsonResponse(serializer.data, safe=False)

    def post(self, request, *args, **kwargs):
        hotel = request.data.get('hotel')
        images = dict((request.data).lists())['image']
        flag = 1
        arr = []
        for img_name in images:
            modified_data = modify_input_for_multiple_files(hotel, img_name)
            file_serializer = PhotoSerializer(data=modified_data)

            if file_serializer.is_valid():
                file_serializer.save()
                arr.append(file_serializer.data)
            else:
                flag = 0

        if flag == 1:
            return Response(arr, status=status.HTTP_201_CREATED)
        else:
            return Response(arr, status=status.HTTP_400_BAD_REQUEST)

希望这能帮助你或任何陷入困境的人。如果有任何问题,请将其拍摄下来。

错误似乎出现在序列化程序中。我必须设置
use\u url=True

序列化程序:

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

class PhotoViewSet(viewsets.ModelViewSet):
    serializer_class = FileListSerializer
    parser_classes = (MultiPartParser, FormParser,)
    queryset=Photo.objects.all()
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

扩展答案

class PhotoSerializer(ModelSerializer):
    class Meta:
        model = Photo
        fields = (
            "image",
            "hotel",
        )
上面的答案有效,但会生成一个大的空数组。 为了使代码正常工作,我必须在Story和Story_Media中分离我的两个模型。故事媒体的每个实例都包含一个图像,并为故事提供一个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_媒体实例。在我的例子中,即使没有上传图像,也有必要创建一个故事,因此这两个条件包括在内

# 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


你是如何上传照片的?@Paul通过邮递员。谢谢你的回答。我尝试在文件列表中添加多个文件。在我看来,您的代码假定每个文件都有一个单独的表单?代码假定您正在将照片添加到另一个模型,如博客照片、用户照片等。但是您可以轻松自定义代码,以便只上载照片,而不必绑定到另一个模型。我遇到了相同的问题。你的方法对我帮助很大。我试过你的方法,它工作得很好,但是当通过postman上传文件时,它显示了一个巨大的空数组。你知道为什么会这样吗?是的,我遇到了空数组的同样问题并解决了它。当我回到电脑后,让我分享我的代码。好的,谢谢。。正在找你的答复你能帮我站起来吗?Thanks@Mitesh我延长了我的回答。