2013-03-04 13 views
9

list_displayに外部キーフィールドを含むModelAdminクラスがあります。しかし、そのモデルの管理者リストページでは、数百のクエリが実行されています.1つの行につき1つのクエリを使用して、結合(select_related())ではなく別のテーブルからデータを取得します。この場合、Djangoの管理者list_select_relatedが動作しないのはなぜですか?

DjangoのドキュメントindicateあなたはModelAdminに属性としてlist_select_related = Trueを追加してこれを削除することができますが、それはまったく機能しません。 This SO questionも同様の問題があるようですが、彼の解決策は不明で、私の場合はうまくいかないのです。

は、ここに私のモデルとモデル管理者のカットダウン版です。しかし

class Device(models.Model): 
    serial_number = models.CharField(max_length=80, blank=True, unique=True) 
    label = models.CharField(max_length=80, blank=True) 

    def __str__(self): 
     s = str(self.serial_number) 
     if self.label: 
      s += ': {0}'.format(self.label) 
     return s 

class Event(models.Model): 
    device = models.ForeignKey(Device, null=True) 
    type = models.CharField(max_length=40, null=False, blank=True, default='') 

class EventAdmin(admin.ModelAdmin): 
    list_display = ('__str__', 'device') 
    list_select_related = True 

list_selected_related = Trueは何も変更していないと付け加えました。私はまだ、この代わりに、SQLのようにクエリの多くを得るに参加:

Lots of queries, not a join

すべてのアイデアは、Djangoの管理者は私のlist_select_relatedとやっNクエリを無視しているように見える理由は?私はPython 2.7とDjango 1.3.3を使用しています。

答えて

14

ここでの問題は、を設定すると基本的にselect_related()がクエリに追加されますが、その呼び出しはデフォルトでForeignKeysにnull=Trueという名前で従わないことになります。だから、答えはチェンジが自分で使用するクエリセットを定義し、従うことFKを指定することです:

class EventAdmin(admin.ModelAdmin): 
    list_display = ('__str__', 'device') 
    def queryset(self, request): 
     return super(EventAdmin, self).queryset(request).select_related('device') 
+2

ありがとうございます!外部キーの 'null = True'は、selected_relatedがそのことを行うことを確実に妨げていました。私は、私が[docs](https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.select_related)のすべての方法を実行したかどうか、 "デフォルトでselect_related()はnull = Trueの外部キーに従わないことに注意してください" –

+0

興味深いことに、なぜ 'list_select_related = True'がDjangoのデフォルトでないのか知っていますか?管理者ですか?それははるかに賢明なデフォルトと思われます。 (なぜデフォルトで 'select_related()'がnull = Trueの外部キーに従わないのかはパフォーマンス上の問題かもしれませんが、 'list_select_related'については疑問に思っています) –

+0

In Django> = 1.6メソッドの名前は 'get_queryset'になりました。 – TAH

6

Since Django 1.6list_select_relatedselect_related()コールに含める項目の名前をブール、リストやタプルを受け入れます。 これで、次を使用できます。

class EventAdmin(admin.ModelAdmin): 
    list_display = ('__str__', 'device') 
    list_select_related = ['device'] 
関連する問題