2017-04-26 7 views
2

インラインモデルが1つのモデルのDjango管理ページがあります。インラインモデルに多くの項目(75など)がある場合、ページは非常にゆっくりとロードされます(30秒のオーダー)。これは、インラインモデルのすべてのフィールドを除外しても、名前をレンダリングしても同じです。インラインモデルを削除すると、ページが非常に速く(秒単位で)読み込まれます。Django管理ページ(インラインモデルのロードが非常に遅い)

このページの読み込みを高速にするにはどうすればよいですか?

+0

私はこの一般的なソリューションを使用して終了https://stackoverflow.com/a/44932400/3124746 –

答えて

6

このページの読み込みを高速化するためにできることは2つあります。

  1. セットDEBUG = False
  2. インラインモデルのレンダリングで使用されるデータベースクエリをキャッシュします。

DEBUG = Falseの

ゆっくりとページが読み込まその理由は、Djangoの管理者は、インラインモデルのインスタンスごとにサブテンプレートをレンダリングしていることです。 75種類のインラインモデルを使用すると、コンテンツが最小限であっても75の余分なテンプレートがレンダリングされます。通常、テンプレートのレンダリングは非常に高速ですが、DEBUG = Trueがある場合、Djangoはデバッグモードのエラーページに余分なコンテキストを挿入しているため、レンダリングするすべてのテンプレートに余分なオーバーヘッドが発生します。この余分なオーバーヘッドは、通常、1ページのテンプレートをレンダリングするだけであるため、通常気付かれません。ただし、75個のテンプレートをレンダリングすると、顕著な遅延(75 * 0.4秒= 30秒)が加わります。


キャッシュデータベースは

を照会少なくともジャンゴ1.10のように、インラインモデルは、インラインモデルの各インスタンスのためにそれをレンダリングするために必要なデータベース照会を行います。インラインモデルにインラインモデルに外部キーがある場合、データベース接続が遅い場合は、これはかなり非効率的になります。このテクニックは、インラインクラス(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

私は少し私のインラインをスピードアップするために、このソリューションを活用し、今私は、要素内の問題を持っていますインラインはセレクトに実際の値を表示していません。 モデル:Serial_Rollにはラベルがたくさんあります。 各ラベルには、重み、味、およびステータスがあります。 (これらはすべて外部キーです) 各ロールには1000以上のラベルがあります。インラインで各FKの現在の値を表示するだけでなく、選択リストにも他の選択肢があります。 これを変更する必要はありますか? –

+0

@AndyPoquetteこれはすべて、インラインのFKの選択を無効にします。現在の値の選択を保持する必要があります。投稿されたソリューションにバグがある場合は、私に知らせてください。 – Zags

+0

私はそれがあなたではないと確信しています。私は私の問題とは別の解決策を選んだが、ありがとう! –

関連する問題