wake-up-neo.net

Django - wie erstellt man eine Datei und speichert sie im FileField eines Modells?

Hier ist mein Modell. Ich möchte eine neue Datei generieren und die vorhandene überschreiben, wenn eine Modellinstanz gespeichert wird:

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)

Ich sehe eine Menge Dokumentation zum Hochladen einer Datei. Aber wie kann ich eine Datei generieren, sie einem Modellfeld zuweisen und Django an der richtigen Stelle speichern? 

77
Greg

Sie wollen FileField und FieldFile in den Django-Dokumenten und insbesondere FieldFile.save () sehen.

Im Grunde gibt ein als FileField deklariertes Feld eine Instanz der Klasse FieldFile an, mit der Sie auf verschiedene Arten mit der darunterliegenden Datei interagieren können. Was Sie also tun müssen, ist:

self.license_file.save(new_name, new_contents)

dabei ist new_name der von Ihnen gewünschte Dateiname und new_contents der Inhalt der Datei. Beachten Sie, dass new_contents eine Instanz von Django.core.files.File oder Django.core.files.base.ContentFile sein muss (siehe die angegebenen Links zum Handbuch für Details). Die zwei Möglichkeiten laufen auf:

# 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'))
116
tawmas

Die akzeptierte Antwort ist sicherlich eine gute Lösung, aber so habe ich versucht, ein CSV zu erstellen und aus einer Sicht zu bedienen.

#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

Ich dachte, es hat sich gelohnt, dies hier zu platzieren, da ich ein wenig herumgefahren war, um das gewünschte Verhalten zu erreichen (vorhandene Datei überschreiben, an der richtigen Stelle speichern, keine doppelten Dateien erstellen usw.).

Django 1.4.1

Python 2.7.3

20
markdsievers

Danke @tawmas. Darüber hinaus,

Ich habe eine Fehlermeldung erhalten, wenn ich den Dateimodus beim Öffnen der Datei nicht angegeben habe. So,

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

Für die Zip-Art der Datei

f = open('/path/to/file.Zip', 'rb')
0
rajagopalx