Python 如何使用django rest api上载多个文件?
我正在尝试使用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
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我延长了我的回答。