これを行うための組み込みの方法はありません。しかし、私は自分のブログselect_related
に一般的な関係をシミュレートするためのテクニックを投稿しました。
要約されたブログコンテンツ:
Djangoの_content_object_cache
フィールドを使用して、基本的select_related
に一般的な関係用に独自のフィールドを作成できます。
generics = {}
for item in queryset:
generics.setdefault(item.content_type_id, set()).add(item.object_id)
content_types = ContentType.objects.in_bulk(generics.keys())
relations = {}
for ct, fk_list in generics.items():
ct_model = content_types[ct].model_class()
relations[ct] = ct_model.objects.in_bulk(list(fk_list))
for item in queryset:
setattr(item, '_content_object_cache',
relations[item.content_type_id][item.object_id])
ここでは、クエリセットのリレーションシップで使用されるすべての異なるコンテンツタイプと、それぞれの個別のオブジェクトIDのセットを取得し、組み込みのin_bulk managerメソッドを使用して、すべてのコンテンツタイプを一度に取得します。 -IDでキー設定された辞書を使用します。次に、コンテンツタイプごとに1つのクエリを実行し、再びin_bulkを使用して、すべての実際のオブジェクトを取得します。
最後に、関連するオブジェクトをソースアイテムの_content_object_cacheフィールドに設定するだけです。これを行う理由は、x.content_objectを直接呼び出した場合に、これがDjangoがチェックし、必要に応じて入力する属性であるためです。事前に入力することで、Djangoが個々のルックアップを呼び出す必要がないことを保証します。実際、私たちが行っているのは、ジェネリックリレーションに対して一種のselect_related()を実装することです。