Как стать автором
Поиск
Написать публикацию
Обновить

Комментарии 15

Что люди только не делают лишь бы документацию не читать :) Django ImageField (Точнее FileField от которого он наследуется) и в версии 1.8, и в версии 3.0 позволяет использовать функцию для определения пути.

upload_to may also be a callable, such as a function. This will be called to obtain the upload path, including the filename. This callable must accept two arguments and return a Unix-style path (with forward slashes) to be passed along to the storage system.


def user_directory_path(instance, filename):
    # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
    return 'user_{0}/{1}'.format(instance.user.id, filename)

class MyModel(models.Model):
    upload = models.FileField(upload_to=user_directory_path)
позволяет использовать функцию для определения пути

Тут тоже есть свои неудобства, которые описаны в упоминаемой вами документации.


instance — In most cases, this object will not have been saved to the database yet, so if it uses the default AutoField, it might not yet have a value for its primary key field.

То есть, на момент вызова функции переданной в upload_to, instance еще не будет сохранен в базу, а значит, id у него будет равен None.


На SO есть несколько решений этой проблемы особенности, надеюсь, другие джангисты поделятся популярным самым решением.

так это плюс, а не минус. все картинки обычно сохраняют в темп, а уже потом переносят куда надо (после пост обработки — сжатие, создания thumb и так далее)

Да на самом деле, без id в пути к файлу, обойтись можно. Урлы же потом ручками редко кто строит, а берут его из модели.
Обычная практика, вообще для имени файла какой нибудь uuid использовать, ну и по папкам разбивать (например по датам), если ожидается много файлов.

Часто используемый вариант для картинок где в пути важен именно primary key (хотя как по мне если есть путь и обработка дубликатов с автопереименованием уже встроена в storage по дефолту для File/Image field) можно спокойно использовать UUID field в качестве primary key:

import uuid
from django.db import models

def directory_path(instance, filename):
    return 'images/{0}/{1}'.format(instance.id, filename)

class MyUUIDModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    upload = models.FileField(upload_to=directory_path)

В базе данных можно хранить только имя картинки, а искать, где она лежит, в настройках. Я использую Flask, но большой роли это не играет. Картинки у меня — обычные строковые поля. Для каждой модели есть свой путь к папке с изображениями и подпапка, сгенерированная например из ID записи с этим полем. В итоге если мне нужно вывести в шаблон путь к картинке, это выглядит примерно так:


f'{path_to_model_images}/{x.id}/{x.image_name}'
FileField и ImageField в базе как раз и хранят путь к файлу в рамках стораджа который указан для поля модели (а стораджами могут быть кто угодно от файлов до aws s3)
НЛО прилетело и опубликовало эту надпись здесь
на OS AIX 6 и 7 дефолтное ограничение 32к файлов в папке, убирается настройкой лимитов
НЛО прилетело и опубликовало эту надпись здесь
Здесь не принято всё пихать в классы, потому что язык иначе не позволяет группировать функциональность.

можно этот момент пояснить?
Каким образом язык не позволяет группировать функциональность?
НЛО прилетело и опубликовало эту надпись здесь
Никогда на Java не писал
НЛО прилетело и опубликовало эту надпись здесь
Как показывает опыт «писать java на python» крайне хорошая практика. Понижает вход в проект, повышает простоту поддержки кодовой базы. Уменьшает количество ошибок. + 100% аннотации (типы данных, параметры и т.д.)

сам джавист 4 года
питонист 3 года
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации