2013-01-09 128 views
20

我的某個模型存在問題。我正在上傳一張圖片,並且我想存儲該id(數據庫表中的pk),但我需要知道Django將在哪一點訪問self.idDjango - 如何在保存新對象時獲取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

在當前的代碼中,當我創建一個新的對象,我會落得像一個網址:

MultimediaData/HelpAdImages/ItemKind/None/somefile.jpg 

,我需要有類似:

MultimediaData/HelpAdImages/ItemKind/35/somefile.jpg 

任何線索?

+0

您可以突出顯示「url()」函數的使用位置嗎? – tushar747

+0

它用於字段圖像中,「image = models.ImageField(upload_to = url,null = True,blank = True)」。當圖像上傳時,該方法被激活。 –

回答

22

如果它是一個新的對象,你需要先保存它,然後訪問self.id,因爲

"There's 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/

+0

嗨!感謝您的回覆。任何想法如何上傳保存)方法內的圖像?祝好, –

+3

@André您需要保存兩次,保存它,訪問該ID,然後更新模型並再次保存。 –

+0

@QiangJin你是什麼意思保存兩次?保存它,訪問該ID。我似乎仍然無法做到。你可以發佈一些示例代碼PLEASSEE –

4

您可能需要兩次保存此文件/實例:

您可以在查找創建標誌的模型上使用post_save信號,並重新保存更新url的實例(並根據需要移動/重命名該文件),因爲實例現在將具有ID。確保你只在創建時才這樣做,否則你會連續循環保存:節省開啓後保存信號的功能,保存後會啓動後保存信號...

請參閱https://docs.djangoproject.com/en/dev/ref/signals/#post-save

-3

我知道這是一箇舊的,但我認爲這可能對某人有用,目前似乎工作確定。

Views.py

#Queries model and appends id's 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 

然而,林不知道有多好,這將大數據塊進行。

+2

此代碼是危險的,不應該使用。在多用戶環境中,在將行插入到數據庫之前,您無法保證id將會是什麼。如果兩個用戶在執行保存之前最終執行此代碼,則最終將出現重複的主鍵和一個插入_will_失敗。 – Tony

-3
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 
+2

此代碼是危險的,不應使用。在多用戶環境中,在將行插入到數據庫之前,您無法保證id將會是什麼。如果兩個用戶在執行保存之前最終執行此代碼,則最終將出現重複的主鍵,並且一個插入操作將失敗。 – Tony

+0

這是獲取ID的方式,問題是「如何獲得自我身份證」。所以如果解決方案有效並且可以使用 - 那意味着這是可行的解決方案。使用它或不使用 - 取決於每個開發人員! – mexekanez

+0

僅僅因爲這種方法在一個用戶的開發環境中工作,不會**意味着這是一個有效的解決方案。我絕對不會將此代碼放在具有多個用戶的生產服務器上。它在某些時候會失敗。 – Tony

1

注意:您需要有models.AutoField(primary_key=True)屬性集,否則數據庫將與新的標識來更新,但Django會認不出來了。

models.AutoField(primary_key=True) 
相關問題