Подтвердить что ты не робот

Django - Как получить self.id при сохранении нового объекта?

У меня проблема в одной из моих моделей. Я загружаю изображение, и я хочу сохранить id (pk в таблице базы данных), но мне нужно знать, в какой момент Django будет иметь доступ к self.id.

models.py

class BicycleAdItemKind(MPTTModel):
    def url(self, filename):
        pdb.set_trace()

        url = "MultimediaData/HelpAdImages/ItemKind/%s/%s" % (self.id, filename)
        return url

    def item_kind_image(self):
        return '<img align="middle" src="/media/%s" height="60px" />' % self.image
    item_kind_image.allow_tags = True     

    # Bicicleta completa, Componentes para bicicleta, Acessorios para ciclista
    n_item_kind      = models.CharField(max_length=50) 
    parent           = TreeForeignKey('self', null=True,
                                      blank=True, related_name='children')
    description      = models.TextField(null=True, blank=True)
    image            = models.ImageField(upload_to=url, null=True, blank=True)
    date_inserted    = models.DateTimeField(auto_now_add=True)
    date_last_update = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.n_item_kind

    class MPTTMeta:
        order_insertion_by = ['n_item_kind']

Проблема заключается в методе url(); Я могу получить self.id только при обновлении объекта, я не получаю self.id при создании нового объекта. Как я могу изменить эту модель, чтобы получить self.id при создании нового объекта?

С текущим кодом, когда я создаю новый объект, я получаю URL-адрес, например:

MultimediaData/HelpAdImages/ItemKind/None/somefile.jpg

И мне нужно иметь что-то вроде:

MultimediaData/HelpAdImages/ItemKind/35/somefile.jpg

Любые подсказки?

4b9b3361

Ответ 1

Если это новый объект, вам нужно сначала его сохранить, а затем получить доступ к self.id, потому что

"There no way to tell what the value of an ID will be before you call save(), 
 because that value is calculated by your database, not by Django."

Проверьте документ django https://docs.djangoproject.com/en/dev/ref/models/instances/

Ответ 2

Возможно, вам потребуется сохранить этот файл/экземпляр дважды:

Вы можете использовать сигнал post_save на модели, которая ищет созданный флаг, и повторно сохраняет экземпляр, обновляющий url (и перемещая/переименовывая файл по мере необходимости), так как экземпляр теперь имеет идентификатор. Удостоверьтесь, что вы делаете это только при условии создания, но в противном случае вы будете непрерывно циклически сохраняться: сохранение начинается с сигнала после сохранения, что делает сохранение, которое запускает сигнал после сохранения...

См. https://docs.djangoproject.com/en/dev/ref/signals/#post-save

Ответ 3

Примечание. Необходимо установить атрибут models.AutoField(primary_key=True), иначе база данных будет обновлена ​​новым идентификатором, но Django не узнает его.

models.AutoField(primary_key=True)

Ответ 4

Я понимаю, что это старо, но для любого, кто столкнется с этим в будущем, вот как вы это делаете сейчас в Django.

def url(instance, filename):
        pdb.set_trace()

        url = "MultimediaData/HelpAdImages/ItemKind/%s/%s" % (instance.id, filename)
        return url

Ответ 5

Я знаю, что это старый, но я подумал, что это может быть полезно кому-то, похоже, работает до сих пор.

Views.py

    #Queries model and appends id to list
    try:
        qs = YourModel.objects.all()
        qslist = []

        for item in qs:
            qslist.append(item.id)

        newid = int(max(qslist) + 1)
    #If no entries are found, assume this is the first entry.
    except:
        newid = 1

Однако я не уверен, насколько хорошо это будет выполняться на больших БД.

Ответ 6

  q = Order.objects.values_list('id', flat=True).order_by('-id')[:1]
            if len(q):
                self.number = str(self.id) if self.id else str(int(q.get()) + 1)
            else:
                self.number = 1