如何使用姜戈睡觉接口上传多个文件?
问题描述
我正在尝试用姜戈睡觉接口上传多张图片。我遵循了以下approach。但是,当我选择一个或多个文件并尝试将它们作为表单数据发送到服务器时,我收到以下错误消息:
AttributeError at /api/photo/ 'bytes' object has no attribute '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()
URL
router.register('api/photo', PhotoViewSet, 'photocreate')
我不知道如何处理该错误,因为我的代码中没有任何与";name";相关的内容?
解决方案
错误似乎在序列化程序中。我必须设置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
]
相关文章