Вопрос по python – Django: Как сохранить оригинальное имя файла в FileField?

12

Я хочу, чтобы имена файлов были случайными, и поэтому я используюupload_to функция, которая возвращает случайное имя файла примерно так:

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)

Однако я хотел бы сохранить исходное имя файла в атрибут внутри модели. Как то так не работает

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)

Как мне это сделать?

Спасибо.

Какая версия Django вы. Я 1.4 и не работает для меня. miki725
Я тоже. Не можете ли вы опубликовать соответствующий код вида? Возможно, между твоими тестами и моими есть какая-то принципиальная разница. rantanplan
как только вы сделаете это и запросите объект из db, вы все еще видите значение для имени файла? miki725
Да. Я на самом деле проверил это внутри оболочки. Я убил его, запустил снова и имя файла было там. На самом деле сначала я подумал, что вы просто забыли сделатьinstance.save() внутри get_random_filename. Но, похоже, это не нужно. rantanplan
Он отлично работает в моих тестах. Как именно это не работает для вас? Что просходит? Может быть проблема в представлении кода? rantanplan

Ваш Ответ

3   ответа
1

нения. Очевидно, что при запуске вашего get_random_filename вам нужно будет сохранить исходное имя файла в памяти.

# 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...
Что мне не нравится в этом, так это то, что сохранение должно произойти дважды. Я бы предпочел что-то более аккуратное. miki725
8

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

Обратите внимание на переключение порядка полей выше.

Это не сработает, потому что:upload_to() вызываетсяpre_save(), здесь в кодекогда фактическое значениеFileField необходимо. Вы можете обнаружить, что присвоение атрибутуfilename вupload() после генерации первого параметраfilename во вставке sql. Таким образом, назначение не вступает в силу в сгенерированном SQL и влияет только на сам экземпляр.

Если это не проблема, пожалуйста, опубликуйте код, который вы ввели в оболочку.

И спасибо за указание, где это происходило. Я копал поля и модели кода, но не думал искать в sql. miki725
Кажется, с Django 1.5 не работает ... Я был вынужден добавитьsuper(FooModel, self).save(update_fields=['filename']) в моей модели сохранить переопределенный метод. Какие-нибудь мысли ?
Это было прямо на месте. Я повторно набрал основной код в вопросе, не осознавая, что изменил порядок. Большое спасибо!!!!! miki725
-1

https://docs.djangoproject.com/en/dev/topics/db/models/

def save(self, *args, **kwargs):
        do_something()
        super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
        do_something_else()
ответил на другой вопрос?

Похожие вопросы