Pull to refresh

Comments 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)
UFO landed and left these words here
на OS AIX 6 и 7 дефолтное ограничение 32к файлов в папке, убирается настройкой лимитов
UFO landed and left these words here
Здесь не принято всё пихать в классы, потому что язык иначе не позволяет группировать функциональность.

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

сам джавист 4 года
питонист 3 года
Sign up to leave a comment.

Articles