4

私はこのようなモデルを持っています:

class Thing(models.Model):
    property1 = models.IntegerField()
    property2 = models.IntegerField()
    property3 = models.IntegerField()

class Subthing(models.Model):
    subproperty = models.IntegerField()
    thing = modelsForeignkey(Thing)
    main = models.BooleanField()

各フィルターの形式が {'type':something, 'value':x} であるフィルターのリストを渡す関数があります。この関数は、すべてのフィルターをまとめて ANDing した一連の結果を返す必要があります。

final_q = Q()
for filter in filters:
        q = None
        if filter['type'] =='thing-property1':
            q = Q(property1=filter['value'])
        elif filter['type'] =='thing-property2':
            q = Q(property2=filter['value'])
        elif filter['type'] =='thing-property2':
            q = Q(property3=filter['value'])
        if q:
            final_q = final_q & q
return Thing.objects.filter(final_q).distinct()

各 Subthing にはブール プロパティ「main」があります。すべてのモノには、main==True のサブシングが 1 つだけあります。

Subthing wheremain==TrueとSubthing を持つすべての Thing を返すフィルターを追加する必要があります。subproperty==filter['value']

Q構築中のオブジェクトの一部としてこれを行うことはできますか? そうでない場合はどうすればいいですか?新しいフィルターの前に取得するクエリセットは非常に大きくなる可能性があるため、結果のループを伴わない方法が必要です。

4

2 に答える 2

2

モノとの関係でサブシングに明示的に「related_name」を与えると、少し理解しやすくなります

class Subthing(models.Model):
    ...
    thing = models.ForeignKey(Thing, related_name='subthings')
    ...

ここで、Django 結合構文を使用して Q オブジェクトを構築します。

Q(subthings__main=True) & Q(subthings__subproperty=filter['value'])

逆の関係はデフォルトで「subthing_set」という名前になっていますが、「subthings」などのより適切な名前を付けた方がわかりやすいと思います。

于 2009-11-28T23:46:38.180 に答える
1

使用する(最初の代わりにfinal_q=Q()

final_q=Q(subthing_set__main=True)
sub_vals = map(lambda v: v['value'], filters)
if sub_vals:
    final_q = final_q & Q(subthing_set__subproperty__in=sub_vals)

ループを調整して sub_vals リストを作成し、ループの後に適用することもできます。

subthing_set は、関連する Subthing にアクセスするために Thing に追加された関連フィールドを自動的に追加します。

別の関連する名前を割り当てることができます。

thing=models.ForeignKey(Thing,related_name='subthings')
于 2009-11-28T23:42:39.483 に答える