adminモデルのget_queryset
メソッドをオーバーライドできます。私はこれを使って、OneToOneField
またはManyToManyField
のオブジェクトを選択/プリフェッチします。ただし、モデルのリストビューには簡潔な情報しか表示されず、変更ビューにはさらに多くのオブジェクトが表示されます。これらが表示されない場合は、リストビューでManyToManyField
関係をプリフェッチすることは意味がありません。Django Adminのリストビューと変更ビューのクエリーセット最適化の違い
サンプルモデル:
class Location(TimeStampedModel):
owner = models.ForeignKey('Profile', on_delete=models.CASCADE)
postcode = models.CharField("postcode", max_length=11, blank=True)
tenants = models.ManyToManyField('Profile', blank=True)
サンプル管理モデル:
@admin.register(Location)
class LocationAdmin(admin.ModelAdmin):
list_display = ('owner', 'postcode')
fields = ('owner', 'postcode', 'tenants')
filter_horizontal = ('tenants',)
def get_queryset(self, request):
qs = super(LocationAdmin, self).get_queryset(request).select_related('owner__user')
qs = qs.prefetch_related('tenants')
return qs
それはクエリセットはモデルのリストビューのために返され、クエリセットが返さごとに異なる最適化を定義することは可能です同じモデルの変更/追加ビュー?
つまり、上記のサンプル管理モデルでは、qs.prefetch_related('tenants')
行が変更/追加ビューにのみ関係しますか?
ありがとうございます! 'add'ビューは' get_queryset'を使用しません...私の場合、 'tenants'の水平ウィジェットは、システム内の各' User'(4000ユーザー= 4000追加クエリ)に対して別々のクエリを引き起こしていました。 'prefetch_related'と' select_related'はかなり最適化されていました。それは 'Profile'の' __str__'メソッドが 'User'モデルの情報に依存していたからです。 – interDist
あなたが提案しているこの方法はどのように「ハッキー」ですか?それはDjangoの次のリリースで壊れませんか?一方、私は 'change_view'、' add_view'、 'changelist_view'関数をオーバーライドして、異なる最適化を提供しました。 – interDist
'Profile'の' __str__'メソッドを修正するために、 'prefetch_related'呼び出しをデフォルトのマネージャ' get_queryset'メソッドに追加することもできます。 – spookylukey