Получение значения первичного ключа перед сохранением

В следующей модели я пытаюсь использовать поле ID модели (UUID) в пути upload_to, но оно определяется как None, предположительно, поскольку оно не было сгенерировано в этот момент.

Если я использую поле UUID, которое не определено как первичный ключ, оно работает нормально.

Как получить значение поля id в момент выполнения picture_path?

# models.py
    
class Foo(models.Model)
    
  def picture_path(instance, filename):  
    return 'pictures/{0}/{1}'.format(instance.id, filename)
    
  id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
  picture = models.ImageField(upload_to=picture_path, null=True, blank=True)

(я знаю, что django будет автоматически добавлять случайные символы, чтобы избежать дублирования имен файлов, это намеренно упрощенный пример, в реальном приложении необходимо хранить файлы каждой модели в отдельной папке)

Поскольку в вашем примере первичный ключ генерируется как uuid4 и не зависит от счетчика БД - вы можете смело генерировать его заранее.

Другими словами - вам не нужно ждать вставки в DB, чтобы получить первичный ключ - вы можете сделать его сами и затем вставить в DB (будучи практически уверенным, что он уникален - потому что он uuid4)

Итак, в коде исправление будет выглядеть следующим образом:

def picture_path(instance, filename):
    instance.id = str(uuid.uuid4())
    return 'pictures/{0}/{1}'.format(instance.id, filename)

Вызов picture_path выполняется перед save. И когда в save id заполняется извне - он не будет перезаписан Django.

Вернуться на верх