Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用Django Rest框架清除图像?_Python_Django_Image_Rest_Django Rest Framework - Fatal编程技术网

Python 如何使用Django Rest框架清除图像?

Python 如何使用Django Rest框架清除图像?,python,django,image,rest,django-rest-framework,Python,Django,Image,Rest,Django Rest Framework,我原以为我的问题应该由解决,但似乎,无论我发送的是无字符串还是空字符串,DRF都不高兴 我使用的是Django1.11.6和DRF3.7.7 class Part(models.Model): image = models.ImageField(null=True, blank=True) class PartSerializer(serializers.ModelSerializer): class Meta: model = Part fie

我原以为我的问题应该由解决,但似乎,无论我发送的是无字符串还是空字符串,DRF都不高兴

我使用的是Django1.11.6和DRF3.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
类零件(models.Model):
image=models.ImageField(null=True,blank=True)
类PartSerializer(serializers.ModelSerializer):
类元:
型号=零件
字段=('id','image')
类PartDetail(generics.RetrieveUpdateAppiview):
queryset=Part.objects.all()
serializer\u class=PartSerializer
parser_classes=(MultiPartParser,FormParser)
#把图像放进去,效果很好
使用tempfile.NamedTemporaryFile(后缀='.jpg')作为fp:
image=image.new('RGB',(100200))
图像保存(fp)
fp.seek(0)
数据={'image':fp}
self.client.put('/path/to/endpoint',data,format='multipart')
#清除图像,尝试#1
数据={'image':无}
self.client.put('/path/to/endpoint',data,format='multipart')
AssertionError:{'image':['提交的数据不是文件。请检查表单上的编码类型。']}
#清除图像,尝试#2
数据={'image':'''}
self.client.put('/path/to/endpoint',data,format='multipart')
AssertionError:不是无

必须明确指定图像字段以允许其为空

使用以下命令:

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')

查看更多详细信息。

请确保我重新实现了您的代码

Django version:2.0
DRF version:3.7.7 as you say in the question.
首先,结论是您尝试的方法#2在我的测试中是正确的。但是,尝试1无效,我的错误与你的相同。但是,以前保存的映像不会在文件系统中删除。以下是我的测试用例。确保您使用的是DRF提供的客户端,而不是django本身

from PIL import Image
from django.test import Client
import io
import os
import unittest
from rest_framework.test import APIClient
class PutTests(unittest.TestCase):
def generate_photo_file(self):
    file = io.BytesIO()
    image = Image.new('RGBA', size=(100, 100), color=(155, 0, 0))
    image.save(file, 'png')
    file.name = 'test222.png'
    file.seek(0)
    return file


def test_imagetest(self):
    """
    test put Image object
    :return:
    """
    self.client = Client()
    print(os.path.join(os.path.dirname( os.path.dirname(__file__) ), '2018s.jpg'))
    f = self.generate_photo_file()
    data={
        'image': f,
    }
    # if you want to insert image in the testCase please let class PartDetail inherits from ListCreateAPIView.
    self.client.post('/puttestimage/', data=data, format='multipart')

def test_image2test(self):
    # this won't work in my test.
    self.client = APIClient()
    data = {'image': None}
    self.client.put('/puttestimage/1/', data=data, format='multipart')
#
def test_image3test(self):
    # this will work in my test.
    self.client = APIClient()
    data = {'image': ''}
    self.client.put('/puttestimage/2/', data=data, format='multipart')
基本的想法是,我首先在数据库中插入一个图像,然后我通过您的尝试#1和#2清除这个图像

class PartSerializer(serializers.ModelSerializer):
#image=serializers.ImageField(max_length=None,allow_empty_file=True,allow_null=True,required=False)
类元:
型号=零件
字段=('id','image')
类PartDetail(generics.RetrieveUpdateAppiview):
queryset=Part.objects.all()
serializer\u class=PartSerializer
parser_classes=(MultiPartParser,FormParser)
URL模式=[
url(r'puttestimage/(?P[0-9]+)/”,PartDetail.as_view(),name='imageput'),
url(r'puttestimage/',PartDetail.as_view(),name='imageput'),
]

这在
文件的文档字段中有介绍。删除

我将在序列化程序上创建一个
update
方法,该方法将使用ORM调用清除图像

def update(self, instance, validated_data):
     instance.part.delete(save = True)

或者类似的东西。

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

这些都不起作用:

让fd=newformdata();
fd.set('my_file',null);//TypeScript不允许我这么做
fd.set('my_file','');//与您的尝试相同的错误#2
fd.set('my_file',new Blob([]);//关于空文件的错误
最终奏效的是

fd.set('my_file',新文件([],'');
这显然意味着一个没有名字的空文件。这样,我可以发送一个PUT请求,删除附加到对象的文件,并将结果
文件字段保留为空:

this.http.put(url,fd);
其中
this.http
是一个角度
HttpClient
。我不知道如何在Python中构造这样一个PUT请求

要保留文件,请不要在
FormData
上为
'my\u file'
设置任何内容


在Django方面,我使用了
ModelSerializer
的子类作为序列化程序,模型中的底层文件字段有blank=True,null=True的选项。

对不起,我忘了提到我使用的是Django 1.11.6(和DRF 3.7.7)。我尝试了这个,并发送了
None
(尝试1)和
'
(尝试2)产生同样的结果。最短和有效的最佳答案。你是如何解决这个问题的?
def update(self, instance, validated_data):
     instance.part.delete(save = True)