Django - comment créer un fichier et le sauvegarder dans le champ de fichier d'un modèle?
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 modèle est sauvegardé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'affecter à un champ Modèle et faire en sorte que Django le stocke au bon endroit?
3 réponses
vous voulez avoir un oeil à FileField et FieldFile dans le Django docs, et surtout FieldFile.save () .
fondamentalement , un champ déclaré comme un FileField
, lorsqu'il est accédé , vous donne une instance de classe FieldFile
, ce qui vous donne plusieurs méthodes pour interagir avec le fichier sous-jacent. Donc, ce que vous devez faire est:
self.license_file.save(new_name, new_contents)
où new_name
est le nom de fichier que vous souhaitez attribué et new_contents
est le 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 les détails). 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'))
Accepté réponse est certainement une bonne solution, mais ici, c'est la façon dont je suis allé sur la génération d'un fichier CSV et de le servir à partir 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
a pensé qu'il valait la peine de mettre ceci ici car il m'a fallu un peu de bricolage pour obtenir tous les comportements souhaitables (écraser fichier existant, stocker au bon endroit, ne pas créer des fichiers dupliqués etc).
Django 1.4.1
Python 2.7.3
Merci @tawmas. En outre,
j'ai une erreur si Je ne spécifie pas le mode fichier lors de l'ouverture du fichier. So,
f = open('/path/to/file', 'r')
Pour fichier ZIP,
f = open('/path/to/file.zip', 'rb')