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

Vla*_*col 1 django multipartform-data image-uploading django-forms django-rest-framework

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

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

假设我有以下模型:

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/')
Run Code Online (Sandbox Code Playgroud)

我有以下序列化器:

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', )
Run Code Online (Sandbox Code Playgroud)

我还有以下几点看法:

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

当我使用 drf Web 界面时:

在此输入图像描述

Vla*_*col 5

我通过重写创建方法并使图像只读来解决它:

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', )
Run Code Online (Sandbox Code Playgroud)

还要确保从 ModelViewSet 中删除 JsonParser

JSONParser
Run Code Online (Sandbox Code Playgroud)

确保如果你使用Postman,你只使用body的表单数据类型

另请确保添加创建模型“动物”所需的所有字段

不要添加图像字段并使其在序列化器中只读

创建一个新字段并将其命名为文件,并将其类型设置为“文件”而不是“文本”。

该字段的名称必须是file,因为您将使用 getlist('file')。名称必须相同。这就是让我困惑的事情。

在此输入图像描述