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 file
No 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 line
La documentación dice:
Además de la API heredada de
File
, comoread()
ywrite()
,FieldFile
incluye 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
File
es 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