2017-04-26 84 views
2

我有一個Django管理頁面,只有一個內嵌模型的模型。當內聯模型有許多項目(如75)時,頁面加載非常緩慢(大約30秒)。即使我排除了內聯模型中的所有字段,只要呈現名稱即可。刪除內聯模型會導致頁面加載非常快(以秒爲單位)。帶內聯模型的Django管理頁面載入速度很慢

如何讓此頁加載速度更快?

+0

我最終使用這一通用的解決方案https://stackoverflow.com/a/44932400/3124746 –

回答

6

有兩件事你可以做,以加快加載此頁面。

  1. 設置DEBUG = False
  2. 緩存在內聯模型渲染中使用的數據庫查詢。

DEBUG =假

的原因,網頁載入速度緩慢是Django管理被渲染子模板的內聯模型的每個實例。使用內聯模型的75個實例,即使其中包含最少的內容,也可以渲染75個額外的模板。雖然渲染模板的速度通常非常快,但如果您有DEBUG = True,則對於您呈現的每個模板都會產生額外的開銷,因爲Django正在爲其調試模式錯誤頁面(我的系統上的每個模板約爲0.4秒)注入額外的上下文。這額外的開銷通常不明顯,因爲您通常只爲單個頁面渲染少量模板。但是,當渲染75個模板時,這會增加明顯的延遲(75 * 0.4秒= 30秒)。


緩存數據庫查詢

至少爲1.10的Django的,內聯模型將進行必要的數據庫查詢,以使其爲內聯模型的每個實例。如果您的內聯模型在內聯模型中有任何外鍵,那麼如果您的數據庫連接速度很慢,這可能非常低效。當您初始化內聯類的實例(使用get_formsets_with_inlines)時,該技術將針對這些外鍵的選擇運行數據庫查詢,然後用緩存的值替換這些內聯字段的選擇以防止重複此數據庫查詢(使用formfield_for_foreignkey)。

class Manufacturer(models.Model): 
    ... 

class OperatingSystem(models.Model): 
    ... 

class Computer(models.Model): 
    manufacturer = models.ForeignKey(Manufarturer) 
    owner = models.ForeignKey(User) 
    operating_system = models.ForeignKey(OperatingSystem) 
    ... 


class ComputerAdmin(admin.StackedInline): 
    model = Computer 

    def formfield_for_foreignkey(self, db_field, request, **kwargs): 
     field = super(ComputerAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) 
     if db_field.name == "owner" and hasattr(self, "cached_owners"): 
      field.choices = self.cached_owners 
     elif db_field.name == "manufacturer" and hasattr(self, "cached_manufacturers"): 
      field.choices = self.cached_manufacturers 
     elif db_field.name == "operating_system" and hasattr(self, "cached_operating_systems"): 
      field.choices = self.cached_operating_systems 
     return field 


class ManufacturerAdmin(admin.ModelAdmin): 
    inlines = (ComputerAdmin,) 

    def get_formsets_with_inlines(self, request, obj=None): 
     for inline in self.get_inline_instances(request, obj): 
      inline.cached_owners = [(i.pk, str(i)) for i in User.objects.all()] 
      inline.cached_manufacturers = [(i.pk, str(i)) for i in Manufacturer.objects.all()] 
      inline.cached_operating_systems = [(i.pk, str(i)) for i in OperatingSystem.objects.all()] 
      yield inline.get_formset(request, obj), inline 
+0

我利用這個解決方案,以加快我的內聯一點,但現在我遇到的問題,其中的元素內聯不在select中顯示它們的實際值。 我有一個模型:Serial_Roll有很多標籤。 每個標籤都有一個Weight,Flavor和Status。 (這些都是外鍵) 每卷有1000多個標籤。我想讓我的內聯顯示每個FK的當前值,但在選擇列表中還有其他選擇。 我需要更改嗎? –

+0

@AndyPoquette所有這些都覆蓋了內聯FK的選項。它應該保留選擇當前值。如果我在發佈的解決方案中有錯誤,請告訴我 – Zags

+0

我確定這不是你,而是我。我選擇了針對我的問題的不同解決方案,但謝謝! –