2012-08-15 27 views
3
class Product(models.Model): 
    title = models.CharField(max_length=75) 

class Deal(models.Model): 
    product = models.ForeignKey(Product) 
    slug = models.SlugField(max_length=255, unique=True) 

有一個類似的基本設置如上,我想要爲每個交易實例產生獨特的slu using使用它的交易的產品標題和交易本身的id。 IE:"apple-iphone-4s-161"其中161是交易的標識,以前的文字是產品的標題。Django獨特的S by編號

爲此,如何覆蓋Deal模型的save()方法以應用它?

回答

5

當然,您可以簡單地覆蓋模型上的save()方法(或使post_save信號的接收器)。 這將是這樣的:

from django.template.defaultfilters import slugify 

class Deal(models.Model): 
product = models.ForeignKey(Product) 
slug = models.SlugField(max_length=255, unique=True) 

    def save(self, *args, **kwargs): 
     super(Deal, self).save(*args, **kwargs) 
     if not self.slug: 
      self.slug = slugify(self.product.title) + "-" + str(self.id) 
      self.save() 

但什麼是該解決方案醜陋的是,它會擊中兩次數據庫(它被保存兩次)。這是因爲在創建新的交易對象時,它只有在您第一次保存它時纔會擁有編號(並且您無法做太多工作)。

+0

這不是醜陋的,它是唯一的方法。 – 2012-08-16 19:07:09

+0

這是醜陋的 - 因爲這種slu idea的想法本身並不好。我知道這樣做並且忘記了它更容易,但實際上這樣的slu is只不過是數據庫的非規範化。我認爲最好是通過它的id來提及對象,並在視圖和網址中僞裝使用slug。 – jasisz 2012-08-16 22:57:57

1

我這個問題已經顛簸了一下,測試jasisz解決方案,並得到了最大遞歸深度超過了錯誤,所以我撥弄它一點,這是怎麼找我:

def save(self, *args, **kwargs): 
    if not self.id: 
     self.slug = slugify(self.title) 
    super(Node, self).save(*args, **kwargs) 

你可以編輯這個來適合你的需求,它測試這個記錄是否存在,如果不存在,那麼它會創建slug字段,否則是更新並且不需要修改slug字段。

希望它有幫助。

+0

謝謝!在寫「從頭」時,我完全忘了它。 – jasisz 2012-08-16 22:53:58

+0

但是,這不會將ID保存到slu。中。它只會使冠軍頭銜戛然而止,對於OP例子來說,許多頭銜似乎都是一樣的。這就是爲什麼他想添加一個獨特的ID,這樣slug不會拋出重複的異常。 – Algorithmatic 2014-11-05 04:45:14

1

我知道這可能不適合您的情況,但我記得碰到類似的情況。我想我的模型中有created_at字段,它有auto_now=True。什麼呈三角

我塞看起來像這樣

self.slug = '%s-%s' %(
     slugify(self.title), 
     self.created_at 
) 

,或者您可以

self.slug = '%s-%s' %(
     slugify(self.title), 
     datetime.datetime.now() 
) 

只是確保蛞蝓max_length足夠長,以包括完整created_at時間的推移,以及title,以便您不會以非唯一或超過最大長度的異常結束。