如何使用Django Rest Framework清除图像?

epa*_*alm 7 python django rest image django-rest-framework

我认为我的问题是https://github.com/encode/django-rest-framework/issues/937,它应该由https://github.com/encode/django-rest-framework/pull/1003修复但是看来,无论是发送无字还是空字符串,DRF都不满意.

我正在使用Django 1.11.6和DRF 3.7.7

class Part(models.Model):
    image = models.ImageField(null=True, blank=True)

class PartSerializer(serializers.ModelSerializer):
    class Meta:
        model = Part
        fields = ('id', 'image')

class PartDetail(generics.RetrieveUpdateAPIView):
    queryset = Part.objects.all()
    serializer_class = PartSerializer
    parser_classes = (MultiPartParser, FormParser)

# put image, works fine
with tempfile.NamedTemporaryFile(suffix='.jpg') as fp:
    image = Image.new('RGB', (100, 200))
    image.save(fp)
    fp.seek(0)
    data = {'image': fp}
    self.client.put('/path/to/endpoint', data, format='multipart')

# clear image, attempt #1
data = {'image': None}
self.client.put('/path/to/endpoint', data, format='multipart')
AssertionError: {'image': ['The submitted data was not a file. Check the encoding type on the form.']}

# clear image, attempt #2
data = {'image': ''}
self.client.put('/path/to/endpoint', data, format='multipart')
AssertionError: <ImageFieldFile: None> is not None
Run Code Online (Sandbox Code Playgroud)

zap*_*.10 5

您必须明确指定图像字段以允许它为空。

用这个:

class PartSerializer(serializers.ModelSerializer):
    image = serializers.ImageField(max_length=None, allow_empty_file=True, allow_null=True, required=False)

    class Meta:
        model = Part
        fields = ('id', 'image')
Run Code Online (Sandbox Code Playgroud)

查看文档以获取更多详细信息。

  • 我试过这个,发送`None`(尝试#1)和`''`(尝试#2)产生相同的结果。 (2认同)

小智 5

我在尝试编写一个通过 Django REST 框架联系 Django 系统的 Angular 应用程序时遇到了类似的情况。DRF 自动生成用于更新对象的表单。如果对象上有FileField,并且您在提交时没有将文件上传到更新表单中,则框架可以自动删除以前上传的文件,并使该对象根本没有文件。那么该对象的字段为空。我希望我的应用程序具有此功能,即对象可以具有附加文件,但这不是必需的,并且可以附加文件并稍后删除。我尝试通过构造一个FormData对象并将其作为 PUT 请求发送来完成删除,但我无法弄清楚为文件字段指定什么值才能使 DRF 删除以前上传的文件,就像 DRF 自动生成的那样形式。

这些不起作用:

    let fd = new FormData();
    fd.set('my_file', null); // TypeScript wouldn't let me do this
    fd.set('my_file', ''); // Same error as your attempt #2
    fd.set('my_file', new Blob([]); // Error about an empty file
Run Code Online (Sandbox Code Playgroud)

最终起作用的是

    fd.set('my_file', new File([], ''));
Run Code Online (Sandbox Code Playgroud)

这显然意味着一个没有名称的空文件。这样,我可以发送一个 PUT 请求,删除附加到对象的文件并保留结果为FileField空:

    this.http.put<MyRecord>(url, fd);
Run Code Online (Sandbox Code Playgroud)

其中this.httpa 是 Angular HttpClient。我不知道如何在 Python 中构造这样的 PUT 请求。

要将文件保留在原位,请不要'my_file'FormData.

在 Django 方面,我使用 的子类ModelSerializer作为序列化器,并且模型中的底层 FileField 具有选项 Blank=True、null=True。