Django:为特定模型的`QuerySet`对象提供自定义过滤方法

时间:2013-05-15 23:41:13

标签: python django orm

我在Django中定义了一个模型。我想为其QuerySet对象定义一些自定义方法。 (即我想定义自定义方式来过滤该对象的实例,其方式仅限于该模型。)

现在,我可以在Manager上定义这些方法,但是这些方法只能在Manager上访问,而不能在任何单个QuerySet上访问,这是任何类型的结果过滤该模型。

那么:我如何给出模型自定义过滤方法的QuerySet个对象?

2 个答案:

答案 0 :(得分:5)

如果您需要过滤器链接扩展Queryset

我当前项目的一个例子:

from django.db import models
from django.db.models.query import QuerySet

class MemberQuerySet(QuerySet):

    def in_group(self, group):
        return self.filter(group_set__pk=group.pk)

    def not_in_group(self, group):
        return self.exclude(groups_set__pk=group.pk)

class MemberManager(models.Manager):

    def get_queryset(self):
        return MemberQuerySet(self.model, using=self._db)

    def in_group(self, group):
        return self.get_queryset().in_group(group)

    def not_in_group(self, group):
        return self.get_queryset().not_in_group(group)

class Member(models.Model):

    # ...

    objects = MemberManager()

你可以这样做:

Member.objects.in_group(one_group).not_in_group(another_group)

如果您不需要过滤器链接,那么使用自定义方法的经理就足够了。 这在docs中已经很好地涵盖了。

This snippet对于更快的QuerySet插件似乎很不错,但它已经过时了(4年)而且我从未尝试过它

答案 1 :(得分:1)

重新启用此功能,以提供更好,更清晰的方法。

至少从django 1.8开始(没有在任何早期测试过......可能会或可能不会工作,不确定何时引入此API),有更好的方法来做到这一点...

from django.db import models
from django.db.models.query import QuerySet

class MemberQuerySet(QuerySet):
    def in_group(self, group):
        return self.filter(group_set__pk=group.pk)

    def not_in_group(self, group):
        return self.exclude(group_set__pk=group.pk)

    # etc..

class Member(models.Model):
    # fields..

    objects = MemberQuerySet.as_manager()

然后你可以这样做..

Member.objects.in_group(group1).not_in_group(group2)