2011-05-05 56 views
0

這裏有點遺憾。基本上,我在管理部分有一個產品頁面,在底部有一個TabularInline,讓我選擇產品的尺寸並設置價格。這有效,但我試圖得到它,以便它將大小表中的默認價格作爲初始值。從另一個表中填充默認值

我試過如下:

class Size(models.Model): 
    name = models.CharField(max_length=50) 
    default_price = models.DecimalField(max_digits=9, decimal_places=2) 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now_add=True) 

    class Meta: 
     db_table = 'sizes' 
     ordering = ['-created_at'] 
     verbose_name_plural = 'Sizes' 

    def __unicode__(self): 
     return self.name 

    def default_price(self): 
     return self.default_price 

然後

class ProductOption(models.Model): 
    product = models.ForeignKey(Product) 
    size = models.ForeignKey(Size) 
    price = models.DecimalField(max_digits=9, decimal_places=2, default=Size.default_price) 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now_add=True) 

它驗證,但是當我打開管理頁面,我得到如下:

不受約束的方法get_default_price()必須被稱爲Size實例作爲第一個參數(沒有任何代替)

不知道還有什麼地方可以從這裏出發。我一直在查看Django文檔,試圖找到其他的東西來嘗試。有任何想法嗎?

+0

您可能想要將''updated_at''字段更改爲''auto_now'',而不是''auto_now_add',否則它們將與''created_at''字段相同。 – 2011-05-05 08:16:40

回答

0

所以,你可以重寫save方法,如果沒有self.id,你可以先填充其他字段,這就是我最喜歡的解決方案。

只是作爲一個例子:

def save(*args, **kwargs): 
    if not self.id: 
     self.size = SomeOtherModel.objects.get(pk=size) 

    super(Size, self).save(*args, **kwargs) 
+0

我認爲這可能是我嘗試填充後的一個步驟。在管理部分有一個窗體,下拉菜單和價格文本框。我希望在從下拉列表中選擇名稱時預先填充默認價格的文本框。我已經能夠獲得的最遠處是用行ID填充它。我想要的實際數據位於與該表單所附模型不同的表格中。我似乎無法找到一種方法來智能地將駐留在獨立表中的default_price鏈接到由選項表填充的表單。 – Joshua 2011-05-05 04:33:16

0

你有幾個問題在這裏:

Size.default_price是一個可調用的對象,所以蟒蛇正試圖設置你的ProductOption的默認值時,調用它。你可能要找的是:

class Size(models.Model): 
    # Other stuff here 
    @property 
    def default_price(self): 
     return self.default_price 

但是,這會導致另一個更深的錯誤。如果您有以下情況:

size = Size() 
size.default_price 

由於無限遞歸,您將結束StackOverflow。該屬性自行調用。解決方案是讓屬性名稱與屬性不同,或者在這種最簡單的情況下,它的行爲有點像屬性。您可以刪除整個default_price的定義。

但是,您打電話給Size.default_price,如果您在Size(一個類)上調用它,而不是該類的一個實例,則它不會綁定任何內容。

你想實際做什麼是Issac Kelly建議的,但更多的是。

class ProductOption(models.Model): 
    # column definitions 

    def __init__(self, *args, **kwargs): 
     super(ProductOption, self).__init__(*args, **kwargs) 
     if self.size and not self.price: 
      self.price = self.size.default_price 

這意味着,當您實例化一個ProductOption時,它會根據大小自動設置價格,如果還沒有價格的話。

您可能還需要在保存時做此項檢查,否則:

po = ProductOption() 
po.size = Size.objects.get(pk=1) 
po.save() 
# po.price is not set now! 

po = ProductOption.objects.get(pk=po.pk) 
# po.price is set now! 

所以,你可以有以下幾點:

class ProductOption(models.Model): 
    # columns 

    def __init__(self, *args, **kwargs): 
     super(ProductOption, self).__init__(*args, **kwargs) 
     self.set_default_price() 

    def save(self, *args, **kwargs): 
     self.set_default_price() 
     super(ProductOption, self).save(*args, **kwargs) 

    def set_default_price(self): 
     if self.size and not self.price: 
      self.price = self.size.default_price 

注意在超階差( )調用:初始化對象時,我們首先要調用父類的__init__,但在保存時,我們希望(可能)先設置默認值,然後調用父類的save方法。

+0

這很有道理。我現在明確瞭解它背後的邏輯。遇到一個相當模糊的錯誤。 '異常類型:DoesNotExist'。 '如果self.size而不是self.price: self.price = self.size.default_price' 如果我只用self.price替換= '20 .00' 如果我通過代碼運行它從詞幹它沒有例外地加載頁面,但是它沒有在管理表單中設置價格。 它是否受管理代碼影響?我添加了這個評論和代碼給Pastebin。我猜不能把它放在評論中。 [此評論的粘貼盒](http://pastebin.com/K6PVX0ST) – Joshua 2011-05-06 05:19:39

+0

我遇到過很難知道管理員的操作順序的問題。 – 2011-05-06 11:26:15

+0

我確定它可以在控制檯上使用首先,然後嘗試添加管理支持。 – 2011-05-06 11:27:58