2012-02-13 58 views
2

,如果我喜歡寫東西Django的__unicode__和FK很慢

class Chip(models.Model): 
    name  = models.CharField(max_length=16) 
    shortname = models.CharField(primary_key=True, unique=True, max_length = 16) 

    def __unicode__(self): 
    return self.shortname 

class ChipStepping(models.Model): 

    stepping = models.CharField (max_length=16) 
    ChipShortname = models.ForeignKey('Chip', db_column="ChipShortname") 

    def __unicode__(self): 
    return "%s:%s" % (self.ChipShortname, self.stepping) 

class ComponentType(models.Model): 
    name   = models.CharField (max_length=32) 
    ChipStepping = models.ForeignKey('ChipStepping', db_column="ChipStepping") 

    def __unicode__(self): 
    return "%s(%s)" % (self.name, self.ChipStepping); 

class ComponentVendor(models.Model): 
    name  = models.CharField  (unique=True, max_length=16) 
    products = models.ManyToManyField('ComponentType', through='ComponentVendorProduct', related_name='vendors') 

    def __unicode__(self): 
    return "%s" % (self.name) 

class ComponentVendorProduct(models.Model): 
    ComponentVendor = models.ForeignKey('ComponentVendor', db_column="ComponentVendor") 
    ComponentType = models.ForeignKey('ComponentType' , db_column="ComponentType") 

並試圖爲ComponentVendor

class ProductInline(admin.TabularInline): 
    model = ComponentVendor.products.through 
    extra = 0 

class ComponentVendorAdmin(admin.ModelAdmin): 
    inlines = [ProductInline] 
    list_filter = ['products__name'] 
    exclude = ['products'] 

admin.site.register(ComponentVendor, ComponentVendorAdmin) 

創建一個管理頁面,結果頁面可能需要30秒以上。加載 從我做的一些調試中,我發現它重複地爲ChipStepping和Chip創建多餘的奇異查詢,在where子句中使用相同的參數,而不是智能地構建查詢所有數據的查詢。

這個問題簡化,如果我從統一刪除外鍵引用ChipStepping和COMPONENTTYPE

功能

如果有ComponentVendorProducts的供應商足夠的條目我在管理頁面點擊,頁面會花幾分鐘!

有沒有一種方法可以減少管理頁面上的數據庫點擊次數?

回答

6

你的問題來自於一個事實,即Django是做你在ComponentType實例調用__unicode__一個DB調用每次。

你有兩個解決方案,您的問題:

  1. 你重寫你的ProductInlinequeryset方法包括select_related('ChipStepping')(Django的1.3和上級)。
  2. 或者,如果您想在其他地方解決問題,則可能需要更改ComponentType的默認管理器(objectsget_query_set方法以使其包含select_related調用。
+2

謝謝!我在這裏找到相關文檔https://docs.djangoproject.com/en/dev/topics/db/managers/ – matrix10657 2012-02-13 16:12:42