2012-06-05 7 views
11

Ich möchte die Dateinamen zufällig sein und deshalb verwende ich upload_to Funktion, die wie so einen zufälligen Dateinamen zurückgibt:Django: Wie wird der ursprüngliche Dateiname in FileField gespeichert?

from uuid import uuid4 
import os 
def get_random_filename(instance, filename): 
    ext = filename.split('.')[-1] 
    filename = "%s.%s" % (str(uuid4()), ext) 
    return os.path.join('some/path/', filename) 

# inside the model 
class FooModel(models.Model): 
    file = models.FileField(upload_to=get_random_filename) 

Allerdings Ich mag würde im Modell den ursprünglichen Dateinamen auf ein Attribut speichern. So etwas funktioniert nicht:

def get_random_filename(instance, filename): 
    instance.filename = filename 
    ext = filename.split('.')[-1] 
    filename = "%s.%s" % (str(uuid4()), ext) 
    return os.path.join('some/path/', filename) 

# inside the model 
class FooModel(models.Model): 
    file = models.FileField(upload_to=get_random_filename) 
    filename = models.CharField(max_length=128) 

Wie kann ich es tun?

Vielen Dank.

+0

Es funktioniert perfekt in meinen Tests. Wie genau funktioniert es nicht für dich? Was geschieht? Vielleicht liegt das Problem im View-Code? – rantanplan

+0

Sobald Sie dies tun und das Objekt von db abfragen, sehen Sie immer noch den Wert für den Dateinamen? – miki725

+0

Ja. Ich habe es tatsächlich in der Schale getestet. Ich tötete es, startete es erneut und der Dateiname war da. Eigentlich dachte ich zuerst, dass du vergessen hast, in get_random_filename eine 'instance.save()' zu schreiben. Aber es scheint, dass es nicht benötigt wird. – rantanplan

Antwort

8

Der normalerweise geschrieben Code funktioniert, vielleicht der eigentliche Code ist

class FooModel(models.Model): 
    filename = models.CharField(max_length=128) 
    file = models.FileField(upload_to=get_random_filename) 

Hinweis das Umschalten der Reihenfolge der oben genannten Bereichen.

Das wird nicht funktionieren, weil: die upload_to() durch die pre_save(), here in the code aufgerufen wird, wenn der Ist-Wert der FileField erforderlich ist. Sie könnten feststellen, dass die Zuordnung zu dem Attribut filename in der upload() nach der Generierung des ersten Param filename in der Einfügung sql ist. Daher wird die Zuweisung im generierten SQL nicht wirksam und betrifft nur die Instanz selbst.

Wenn das nicht das Problem ist, poste bitte den Code, den du in die Shell eingegeben hast.

+0

Das war genau auf der Stelle. Ich habe den Kerncode in der Frage neu eingegeben, ohne zu bemerken, dass ich den Auftrag umgekehrt habe. Vielen Dank!!!!! – miki725

+0

Und Dank für das Aufzeigen, wo das passiert ist. Ich habe durch Felder und Modelle Code gegraben, aber nicht daran gedacht, in SQL zu suchen. – miki725

+0

Es scheint mit dem Django 1.5 gebrochen zu sein ... Ich wurde gezwungen, 'super (FooModel, self) hinzuzufügen.Speichern Sie (update_fields = ['filename']) '' in meinem Modell die überschriebene Methode. Irgendwelche Gedanken? – dulaccc

1

Sie könnten den Pfad zum Auffüllen des Dateinamens während des Speichervorgangs verwenden. Offensichtlich müssen Sie den ursprünglichen Dateinamen im Speicher speichern, wenn Ihr get_random_filename ausgeführt wird.

# inside the model 
class FooModel(models.Model): 
    file = models.FileField(upload_to=get_random_filename) 
    filename = models.CharField(max_length=128) 

    def save(self, force_insert=False, force_update=False): 
     super(FooModel, self).save(force_insert, force_update) 
      #Do your code here... 
+0

Was mir nicht gefällt ist, dass dann speichern muss twise geschehen. Ich würde etwas lieber bevorzugen. – miki725

Verwandte Themen