/ / Django Querysetを空にするには - django、django-queryset

Django Querysetを空にする方法 - django、django-queryset

チェーンフィルタリングを行ういくつかのメソッドを持つカスタムQuerySetオブジェクトがあります。まず、コンテキストの設定。

from django.db.models import Manager, Model
from django.db.models.query import QuerySet

class MyQuerySet(QuerySet):
def some_filter(self, foo):
return self.filter(some__chain__of__relationships__foo=foo)

class MyModelManager(Manager):
def get_query_set(self):
return MyQuerySet(self.model, using=self._db)

class MyModel(Model):
objects = MyModelManager()

使用事例:

qs = MyModel.objects.get_query_set()
qs = qs.filter_by_name(name).filter_by_color(color).filter_by_date(date)

私はDjangoのEmptyQuerySetではなく、私のオブジェクトの空のクエリーセットを返す必要がある状況があります。

def filter_by_color(self, color):
if color.is_active:
return self.filter(some__chain__of__relationships__color=color)
return self.empty()

どのように定義するか .empty()?私は使用することはできません .none() なぜなら .filter_by_date(date) EmptyQuerySetにはnoがあるためエラーがスローされます .filter_by_date() 方法。私は現在、ハックを使っています where=["1=0"]

def empty(self):
return self.extra(where=["1=0"])

または...:

def empty(self):
return self.filter(pk=0)

私は非ハックの方法でこれを行うことを好むでしょう。

私のカスタムQuerySetオブジェクトの空のクエリセットを返すPythonの方法は何ですか?

回答:

回答№1は1

Django <= 1.5を使用している場合は、 EmptyQuerySet クラスと独自のカスタムクエリーセットクラスです。ただオーバーライドする none() あなたのカスタムクラスを返す:

class MyQuerySet(QuerySet):
def none(self):
# prevent circular import
from . import MyEmptyQuerySet
return self._clone(klass=MyEmptyQuerySet)

class MyEmptyQuerySet(EmptyQuerySet, MyQuerySet):
pass

Django 1.6では、あなたが呼んでもquerysetのクラスは同じです none()しかし、メタクラスの使用とオーバーライド __instancecheck__、呼び出し isinstance(qs.none(), EmptyQuerySet) それでも返されます True。だから、Django 1.6では、カスタムクラスやその他のものは必要ありません。あなたのカスタムクエリーセットクラスの新しいメソッドは、空のクエリーセットでも利用できます。


回答№2の場合は0
qs = qs.filter_by_name(name).filter_by_color(color)
qs = qs.filter_by_date(date) if isinstance(qs, MyQuerySet) else qs

これは私が今すぐ見ることができる最も簡単なことです。あるいは、チェーンの最後に色でフィルターをかけます。