Django FileField с upload_to определяется во время выполнения

123

Я пытаюсь настроить свои загрузки таким образом, что если пользователь joe загружает файл, он переходит в MEDIA_ROOT/joe, а не все файлы идут в MEDIA_ROOT. Проблема в том, что я не знаю, как определить это в модели. Вот как это выглядит в настоящее время:

class Content(models.Model):
    name = models.CharField(max_length=200)
    user = models.ForeignKey(User)
    file = models.FileField(upload_to='.')

Так что я хочу вместо '.' как upload_to, укажите имя пользователя.

Я понимаю, что с Django 1.0 вы можете определить свою собственную функцию для обработки upload_to, но эта функция не имеет представления о том, кто из пользователей будет либо, так что я немного потерян.

Спасибо за помощь!

Теги:
django-models

3 ответа

234
Лучший ответ

Вы, вероятно, читаете документацию, поэтому здесь можно сделать простой пример:

def content_file_name(instance, filename):
    return '/'.join(['content', instance.user.username, filename])

class Content(models.Model):
    name = models.CharField(max_length=200)
    user = models.ForeignKey(User)
    file = models.FileField(upload_to=content_file_name)

Как вы можете видеть, вам даже не нужно использовать указанное имя файла - вы можете переопределить это в своем upload_to вызываемом тоже, если хотите.

  • 0
    Да, это, вероятно, относится к документам - это разумный FAQ по IRC
  • 2
    Это работает с ModelForm? Я вижу, что экземпляр имеет все атрибуты модели класса, но значений нет (только строка имени поля). В шаблоне пользователь скрыт. Возможно, мне придется задать вопрос, я гуглил это часами.
Показать ещё 11 комментариев
12

Это действительно помогло. Для немного более краткого ради, решил использовать лямбда в моем случае:

file = models.FileField(
    upload_to=lambda instance, filename: '/'.join(['mymodel', str(instance.pk), filename]),
)
  • 2
    Это не сработало для меня в Django 1.7 с использованием миграций. Закончилось создание функции вместо, и миграция заняла.
  • 0
    Даже если вы не можете заставить лямбду работать с использованием str (instance.pk), это хорошая идея, если у вас есть проблемы с перезаписью файлов, когда вы этого не хотите.
Показать ещё 2 комментария
3

Заметка об использовании значения pk объекта 'instance'. Согласно документации:

В большинстве случаев этот объект еще не был сохранен в базе данных, поэтому, если он использует AutoField по умолчанию, он может еще не иметь значения для своего поля первичного ключа.

Следовательно, справедливость использования pk зависит от того, как определена ваша конкретная модель.

  • 0
    Я получаю None в качестве значения. Я не могу понять, как это исправить. Вы можете объяснить немного подробнее.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню