8

select_relatedはGenericRelationリレーションに対して機能しますか、それとも合理的な代替手段がありますか?現時点では、Djangoはクエリセット内の各アイテムに対して個別のSQL呼び出しを行っていますが、select_relatedのようなものを使用することは避けたいと思います。

class Claim(models.Model):
    proof = generic.GenericRelation(Proof)


class Proof(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

多数のクレームを選択していますが、個別にクエリするのではなく、関連するプルーフをプルインしたいと思います。

4

3 に答える 3

18

これを行うための組み込みの方法はありません。しかし、私は自分のブログ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()を実装することです。

于 2010-05-31T11:13:33.437 に答える
3

select_relatedとGRが一緒に機能しないようです。同じクエリですべてを取得するClaimのアクセサを作成できると思います。この投稿では、必要に応じて、汎用オブジェクトを取得するための生のSQLに関するいくつかのポインターを提供します。

于 2010-05-30T17:34:42.363 に答える
3

.extra()関数を使用して、フィールドを手動で抽出できます。

Claims.filter(proof__filteryouwant=valueyouwant).extra(select={'field_to_pull':'proof_proof.field_to_pull'})

.filter()は結合を行い、.extra()はフィールドをプルします。proof_proofは、ProofモデルのSQLテーブル名です。複数のフィールドが必要な場合は、辞書でそれぞれを指定してください。

于 2011-02-28T14:03:03.337 に答える