python - proyectos - subir archivo django
Django: ¿cómo crear un archivo y guardarlo en el FileField de un modelo? (3)
Aquí está mi modelo. Lo que quiero hacer es generar un nuevo archivo y sobrescribir el existente siempre que se guarde una instancia 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 puedo generar un archivo, asignarlo a un campo modelo y hacer que Django lo almacene en el lugar correcto?
Desea echar un vistazo a FileField y FieldFile en los documentos de Django, y especialmente a FieldFile.save() .
Básicamente, un campo declarado como FileField
, cuando se accede, le proporciona una instancia de la clase FieldFile
, que le brinda varios métodos para interactuar con el archivo subyacente. Entonces, lo que debes 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
(consulte los enlaces dados al manual para obtener más información). 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''))
Gracias @tawmas. Además de eso,
Obtuve un error si no especifico el modo de archivo mientras abro el archivo. Asi que,
f = open(''/path/to/file'', ''r'')
Para el tipo de archivo ZIP,
f = open(''/path/to/file.zip'', ''rb'')
La respuesta aceptada es sin duda una buena solución, pero esta es la forma en que fui generando un CSV y sirviéndolo desde una perspectiva.
#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 toquetear para obtener todo el comportamiento deseable (sobrescribir el archivo existente, almacenarlo en el lugar correcto, no crear archivos duplicados, etc.).
Django 1.4.1
Python 2.7.3