Pensé que mi problema era https://github.com/encode/django-rest-framework/issues/937 que debería haber sido solucionado por https://github.com/encode/django-rest-framework/pull/1003 pero aparece, ya sea que envíe Ninguno o una cadena vacía, DRF no está contento.
Estoy usando Django 1.11.6 y 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 NoneDebe especificar el campo de imagen explícitamente para permitir que sea nulo.
utilizar esta:
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')consulte los documentos para obtener más detalles.
Me encontré con algo como esto tratando de escribir una aplicación Angular que contacta un sistema Django a través del marco REST de Django. DRF genera automáticamente formularios para actualizar objetos. Si hay un FileField en un objeto y no carga un archivo en el formulario de actualización cuando lo envía, el marco puede eliminar automáticamente un archivo cargado anteriormente y dejar el objeto sin ningún archivo. El campo del objeto es entonces nulo. Quería que mi aplicación tuviera esta capacidad, es decir, los objetos pueden tener un archivo adjunto, pero no es necesario, y se puede adjuntar un archivo y luego eliminarlo. Traté de lograr la eliminación construyendo un objeto FormData y enviándolo como una solicitud PUT, pero no pude averiguar exactamente qué valor especificar para el campo de archivo para hacer que DRF elimine el archivo cargado previamente, como lo que sucede en DRF automáticamente. formularios generados.
Estos no funcionaron:
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 fileLo que finalmente funcionó fue
fd.set('my_file', new File([], '')); lo que aparentemente significa un archivo vacío sin nombre. Con eso, podría enviar una solicitud PUT que elimine el archivo adjunto al objeto y deje el FileField resultante nulo:
this.http.put<MyRecord>(url, fd); donde this.http es un HttpClient angular. No estoy seguro de cómo construir una solicitud PUT de este tipo en Python.
Para dejar el archivo en su lugar, no configure nada para 'my_file' en FormData .
En el lado de Django, estaba usando una subclase de ModelSerializer como serializador, y el FileField subyacente en el Modelo tenía opciones en blanco = Verdadero, nulo = Verdadero.
Esto está cubierto en los documentos para FileField.delete
Crearía un método de update en su serializador que borraría la imagen usando la llamada ORM
def update(self, instance, validated_data): instance.part.delete(save = True)o algo similar.