如何清空Django Queryset

时间:2014-07-07 18:13:12

标签: 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没有.filter_by_date()方法。我目前正在使用黑客where=['1=0']

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

或者...

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

我更愿意以非黑客的方式做到这一点。

什么是Pythonic方式返回自定义QuerySet对象的空查询集?

2 个答案:

答案 0 :(得分: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中,如果您调用none(),则查询集的类仍然相同,但通过使用元类并覆盖__instancecheck__,调用isinstance(qs.none(), EmptyQuerySet)仍会返回{{1} }}。因此,在Django 1.6中,不需要自定义类或任何东西,您的自定义查询集类上的新方法仍然可用于空的查询集。

答案 1 :(得分:0)

qs = qs.filter_by_name(name).filter_by_color(color)
qs = qs.filter_by_date(date) if isinstance(qs, MyQuerySet) else qs

这是我现在能看到的最简单的事情。或者在链的末尾按颜色过滤。