En mi modelo, quiero usar un validador para analizar el contenido de un archivo, lo que no puedo entender es cómo acceder al contenido del archivo para analizarlo ya que el archivo aún no se ha guardado (lo cual es bueno ) cuando los validadores se están ejecutando.
No entiendo cómo obtener los datos del value pasado al validador en un archivo (supongo que debería usar tempfile ) para poder abrirlo y evaluar los datos.
Aquí hay un ejemplo simplificado, en mi código real, quiero abrir el archivo y evaluarlo con csv.
en Modelos.py
class ValidateFile(object): .... def __call__(self, value): # value is the fieldfile object but its not saved # I believe I need to do something like: temp_file = tempfile.TemporaryFile() temp_file.write(value.read()) # Check the data in temp_file .... class MyItems(models.Model): data = models.FileField(upload_to=get_upload_path, validators=[FileExtensionValidator(allowed_extensions=['cv']), ValidateFile()])¡Gracias por la ayuda!
Mire cómo se hace esto en la implementación de ImageField :
Entonces su clase ValidateFile puede ser algo como esto:
from io import BytesIO class ValidateFile(object): def __call__(self, value): if value is None: #do something when None return None if hasattr(value, 'temporary_file_path'): file = value.temporary_file_path() else: if hasattr(value, 'read'): file = BytesIO(value.read()) else: file = BytesIO(value['content']) #Now validate your fileNo es necesario un tempfile :
El value pasado a un validador de FileField es una instancia de FieldFile , como ya lo mencionó el OP.
En el fondo, es posible que la instancia de FieldFile ya use un tempfile.NamedTemporaryFile ( fuente ), o podría incluir un archivo en memoria , pero no debe preocuparse por eso:
Para "evaluar los datos", simplemente puede tratar la instancia de FieldFile como cualquier objeto de archivo de Python.
Por ejemplo, podría iterar sobre él:
def my_filefield_validator(value): # note that value is a FieldFile instance for line in value: ... # do something with lineLa documentación dice:
Además de la API heredada de
File, comoread()ywrite(),FieldFileincluye varios métodos que se pueden usar para interactuar con el archivo subyacente: ...
y la clase FieldFile proporciona
... un envoltorio alrededor del resultado del método
Storage.open(), que puede ser un objeto deFile, o puede ser una implementación de almacenamiento personalizado de la API deFile.
Un ejemplo de una implementación de archivo subyacente de este tipo es InMemoryUploadedFile docs / source .
También de los documentos :
La clase
Filees un contenedor delgado alrededor de un objeto de archivo de Python con algunas adiciones específicas de Django
También tenga en cuenta: validadores basados en clases frente a validadores basados en funciones