2009-07-10 7 views
2

使用してクエリセットは、スパニングヌル関係がモデルを考えてみましょう: ジャンゴ - Q

#Models 
class A(models.Model): 
    fieldOfA = models.CharField(max_length = 4) 
class B(models.Model): 
    fieldOfB = models.CharField(max_length = 4) 
class C(models.Model): 
    classA = models.ForeignKey(A, blank=True, null=True) 
    classB = models.ForeignKey(B, blank=True, null=True) 

私はCのオブジェクトを作成する

は、私は、オブジェクトがクラスAまたはClassBの関係のいずれかを持っていることを確認してください。

私は特定のfieldOfAまたは特定のfieldOfB値に対して私のCのオブジェクトを取得する単一のクエリセットを探しています。

私はこれを試しましたが、失敗しました(有効な結果があっても[]を返します)。

#Views - assume double underscore in the query 
from django.db.models import Q 
my_query = C.objects.filter(Q(classA _ _isnull = False, classA _ _fieldOfA = 'foo') | Q(classB _ _isnull = False, classB _ _fieldOfB = 'foo')) 

私が見る問題は '|'それが適用されます。 classAとclassBの2つの異なるクエリーセットは正常に動作します。私はこの仕事をするために単一のクエリーセットを適用することができますか?あるいは、個々のクエリーセットをマージする方法です。

答えて

2

CにAまたはBがあるが両方が決して存在しないことが確かであれば、isnullの制約は冗長です。あなたが以下を実行するとどうなりますか?

C.objects.filter(Q(classA__fieldOfA = 'foo') | Q(classB__fieldOfB = 'foo')) 

それはまだ、仕事manage.py shellを実行し、上記のクエリを実行した後(settings.DEBUGTrueであることを確実にすること、

>>> from django.db import connection 
>>> connection.queries() 

あなたは何を見ていて上記のために生成されたSQLをチェックしない場合は?

+0

残念ながら、冗長性を排除しても役に立たなかった。 SQLには、両方のQに対して(内部的にINNER JOINが続く)2つの「LEFT OUTER JOINS」があります。 2番目のQは右外部結合を持つべきではありませんか? fieldBの値は復元されません。 助けてくれてありがとう。私は現在、2つのクエリーセットを連鎖しています(ある意味では合併しています)。このコードスニペットの使用 - http://www.djangosnippets.org/snippets/1103/ – tjazz

2

実は、あなたは同じようにQuerySetを組み合わせることができますようなので:。

C.objects.filter(classA__fieldOfA='foo') | C.objects.filter(classB__fieldOfB='foo')