Voici mon modèle. Ce que je veux faire, c'est générer un nouveau fichier et écraser le fichier existant chaque fois qu'une instance de modèle est enregistrée:
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)
Je vois beaucoup de documentation sur la façon de télécharger un fichier. Mais comment puis-je générer un fichier, l’assigner à un champ de modèle et le faire stocker par Django au bon endroit?
Vous voulez regarder FileField et FieldFile dans les documents Django, et en particulier FieldFile.save () .
En gros, un champ déclaré en tant que FileField
, lors de l'accès, vous donne une instance de la classe FieldFile
, qui vous donne plusieurs méthodes pour interagir avec le fichier sous-jacent. Alors, ce que vous devez faire c'est:
self.license_file.save(new_name, new_contents)
où new_name
est le nom du fichier que vous souhaitez attribuer et new_contents
au contenu du fichier. Notez que new_contents
doit être une instance de Django.core.files.File
ou Django.core.files.base.ContentFile
(voir les liens donnés au manuel pour plus de détails). Les deux choix se résument à:
# 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 réponse acceptée est certainement une bonne solution, mais voici comment je me suis mis à générer un fichier CSV et à le servir d’un point de vue.
#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
Je pensais que cela valait la peine de mettre ceci ici, car il m'a fallu un peu de bidouillage pour obtenir tous les comportements souhaitables (écraser le fichier existant, stocker au bon endroit, ne pas créer de fichiers dupliqués, etc.).
Django 1.4.1
Python 2.7.3
Merci @tawmas. En plus de ça,
J'ai une erreur si je ne spécifie pas le mode de fichier lors de l'ouverture du fichier. Alors,
f = open('/path/to/file', 'r')
Pour le type de fichier Zip,
f = open('/path/to/file.Zip', 'rb')