CREATE 上 DRF 中的多部分图像上传

Posted

技术标签:

【中文标题】CREATE 上 DRF 中的多部分图像上传【英文标题】:Multipart Image Upload in DRF on CREATE 【发布时间】:2019-06-19 15:03:04 【问题描述】:

我想要一个模型,您可以在创建(发布)时上传多个图像。

在 api/animals/ 上的 DRF 网络视图中,我想在帖子表单中添加多个图像并创建带有附加图像的新动物。

假设我有以下模型:

class Animal(models.Model):
    slug = models.CharField(max_length=20, unique=True)


class AnimalImage(models.Model):
    animal = models.ForeignKey(Animal, on_delete=models.CASCADE)
    image = models.ImageField(upload_to='animal_pics/')

我有以下序列化程序:

class AnimalImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = AnimalImage
        fields = ('animal', 'image', )


class AnimalSerializer(serializers.HyperlinkedModelSerializer):
     images = AnimalImageSerializer(many=True)
     class Meta:
         model = Animal
         lookup_field = 'slug'
         extra_kwargs = 
             'url': 'lookup_field': 'slug'
         
         fields = ('slug', 'images', )

我有以下休息观点:

 class AnimalViewSet(viewsets.ModelViewSet):
     queryset = Animal.objects.all()
     serializer_class = AnimalSerializer
     lookup_filed = 'slug'
     parser_classes = (JSONParser, MultiPartParser, FormParser)

当我使用 drf 网页界面时:

【问题讨论】:

【参考方案1】:

我通过覆盖 create 方法并将图像设为只读来解决它:

class AnimalSerializer(serializers.HyperlinkedModelSerializer):

     images = AnimalImageSerializer(many=True, read_only=True)

     def create(self, validated_data):
         images_data = self.context['request'].FILES
         animal = Animal.objects.create(
             slug=validated_data.get('slug', 'default-slug')
         )
         for image_data in images_data.getlist('file'):
             AnimalImage.objects.create(animal=animal, image=image_data)

     class Meta:
         model = Animal
         lookup_field = 'slug'
         extra_kwargs = 
             'url': 'lookup_field': 'slug'
         
         fields = ('slug', 'images', )

还要确保从 ModelViewSet 中删除 JsonParser

JSONParser

确保如果你使用 Postman,你只使用 body 的 form-data 类型

还要确保添加创建模型动物所需的所有字段

不要添加 images 字段并使其在序列化程序中只读

创建一个新字段并将其命名为 file 并使其类型为 File 而不是 Text。

字段的名称必须是 file,因为您将使用 getlist('file')。名称必须相同。这让我搞砸了。

【讨论】:

这个答案,是通过 ForeignKey 与 Django REST Framework 的反向关系上传多个图像的最简单的解决方案。我花了一天时间寻找另一种方法。不要浪费你的时间,相信我。 KISS 我找到了一种替代方案的解决方案,您可以使用表单数据上传多个图像,验证并发送嵌套的 json。你可以查看我的answer。

以上是关于CREATE 上 DRF 中的多部分图像上传的主要内容,如果未能解决你的问题,请参考以下文章

IBM Mobilefirst Java HTTP Adapter 中的多部分文件上传

使用“键值”格式的多部分将图像上传到服务器

在IOS中上传带参数的多部分图像

使用 Retrofit 上传 JSON 格式的多部分图像数据?

如何处理Alamofire中的多部分/相关数据?

警告:第 0 行未知中的多部分/表单数据 POST 数据中缺少边界