2017-01-22 25 views
0

私はBaseModel(models.Model)、ExtendedModelA(BaseModel)、ExtendedModelB(BaseModel)を持っています。 ExtendedModelAとExtendedModelBは両方とも、他のモデルへの外部キーフィールドを持っています。それらのユニコードメソッドは、この外部キー関連モデルからフィールドを返します。Django - 拡張モデルの効率的なクエリ

私はBaseModelオブジェクト(当然、ExtendedModelAとExtendedModelBオブジェクトを含む)を取り込みたいドロップダウンメニューを持っています。これを行うには、すべての拡張オブジェクト(タイプAとB)とその関連オブジェクトを取得するクエリーセットが必要です。

私がマージされたクエリセットを持っている:

queryset = BaseModel.objects.filter(type=1).select_related('extendedmodela') | BaseModel.objects.filter(type=2).select_related('extendedmodelb') 

トラブルがBaseModelのUnicode表現がドロップダウンに提示されていることです。

if hasattr(self, extendedmodela): 
     return self.extendedmodela.__unicode__() 
    else: 
     return self.extendedmodelb.__unicode__() 

この結果、オブジェクトごとにデータベースにクエリが実行されます。

この混乱から抜け出す方法についてのアイデアは誰ですか?

基本的には、すべてのBaseModelオブジェクトを効率的に取得するクエリーセットを作成する必要があります。ドロップダウンでそれぞれの拡張クラス(外部キーフィールドオブジェクトのフィールドを表示する)のユニコードメソッドを表示するときに、データベース。私は数千のオブジェクトを持っているので、データベースはヒットします。

乾杯、

ディーン

+0

あなたは 'ExtendedModelA/B'インスタンスのリスト/セットを混ぜ合わせることができませんか? – schwobaseggl

+0

私はよくわかりません - Djangoにはかなり新しいです –

答えて

1

あなたはselect_relatedを使用しています。 Qを使用してクエリを最適化することができます。の場合はタイプ1、この場合はタイプ2のいずれかをフィルタリングすることができます。

from django.db.models import Q 

BaseModel.objects.filter(Q(type=1) | Q(type=2)).select_related('extendedmodela').select_related('extendedmodelb') 

EDIT

あなたは、関連するモデルであり、より深いフィールドにアクセスするために二重アンダースコア表記を使用することができます。例えば。

.select_related('extendedmodela', 'extendedmodela__fkfieldname') 
+0

これは、AとBのUnicodeメソッドが1つずつ取り出さなければならない外部キーにアクセスするという事実を助けるものではありません。あなたは既存の 'select_related'に必要な関係を追加することができます。 – schwobaseggl

+0

したがって、ユニコードの外部キー呼び出しの問題を解決するために、私はちょうどこのクエリに 'select_related'を追加して、外部キーがリンクする有能な名前を渡すことができますか? –

+0

@DeanSherwin二重アンダースコア表記を使用して、関連するモデルのより深いフィールドに到達することができます。 – denvaar

0

はなぜ、ドロップダウンに混合袋を渡しません。これはもはやQuerySetではありませんが、ドロップダウンは気にしません。選択されているものは何でもインスタンス

qs = list(ExtendedModelA.objects.select_related('whatever_fk_needed')) +\ 
    list(ExtendedModelB.objects.select_related('whatever_fk_needed')) 

は、そのBaseModelインスタンスと同じidを持つことになります。

+0

リストに変更するとクエリセットが評価されるため、これを実行しません。代わりに 'values_list'を使うことができます。 – denvaar

+0

クエリーセットは、ドロップダウンがレンダリングされるとすぐに評価されます。 – schwobaseggl

+0

私はそれが本当だと思います。 – denvaar