Django: ¿cómo crear un archivo y guardarlo en el FileField de un modelo?

Aquí está mi modelo. Lo que quiero hacer es generar un nuevo archivo y sobrescribir el existente cada vez que se guarda una instancia del modelo:

class Kitten(models.Model): claw_size = ... license_file = models.FileField(blank=True, upload_to='license') def save(self, *args, **kwargs): #Generate a new license file overwriting any previous version #and update file path self.license_file = ??? super(Request,self).save(*args, **kwargs) 

Veo mucha documentación sobre cómo subir un archivo. Pero, ¿cómo genero un archivo, lo asigno a un campo de modelo y hago que Django lo almacene en el lugar correcto?

Desea echar un vistazo a FileField y FieldFile en los documentos de Django, y especialmente FieldFile.save () .

Básicamente, un campo declarado como FileField , cuando se accede, le brinda una instancia de la clase FieldFile , que le brinda varios métodos para interactuar con el archivo subyacente. Entonces, lo que necesitas hacer es:

 self.license_file.save(new_name, new_contents) 

donde new_name es el nombre de archivo que desea asignar y new_contents es el contenido del archivo. Tenga en cuenta que new_contents debe ser una instancia de django.core.files.File o django.core.files.base.ContentFile (vea los enlaces al manual para los detalles). Las dos opciones se reducen a:

 # Using File f = open('/path/to/file') self.license_file.save(new_name, File(f)) # Using ContentFile self.license_file.save(new_name, ContentFile('A string with the file content')) 

La respuesta aceptada es sin duda una buena solución, pero esta es la forma en que fui para generar un CSV y servirlo desde una vista.

 #Model class MonthEnd(models.Model): report = models.FileField(db_index=True, upload_to='not_used') import csv from os.path import join #build and store the file def write_csv(): path = join(settings.MEDIA_ROOT, 'files', 'month_end', 'report.csv') f = open(path, "w+b") #wipe the existing content f.truncate() csv_writer = csv.writer(f) csv_writer.writerow(('col1')) for num in range(3): csv_writer.writerow((num, )) month_end_file = MonthEnd() month_end_file.report.name = path month_end_file.save() from my_app.models import MonthEnd #serve it up as a download def get_report(request): month_end = MonthEnd.objects.get(file_criteria=criteria) response = HttpResponse(month_end.report, content_type='text/plain') response['Content-Disposition'] = 'attachment; filename=report.csv' return response 

Pensé que valía la pena poner esto aquí, ya que me tomó un poco de juguetear para obtener todo el comportamiento deseable (sobrescribir el archivo existente, almacenar en el lugar correcto, no crear archivos duplicados, etc.).

Django 1.4.1

Python 2.7.3

Gracias @tawmas. Además de eso,

Recibo un error si no especifico el modo de archivo al abrir el archivo. Asi que,

 f = open('/path/to/file', 'r') 

Para el tipo de archivo ZIP,

 f = open('/path/to/file.zip', 'rb')