5

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

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

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

4

2 回答 2

8

如果您需要过滤器链接,请扩展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中有很好的介绍。

这个片段QuerySet对于更快的插件来说似乎不错,但它已经过时(4 年)而且我从未尝试过

于 2013-05-16T00:41:11.373 回答
4

恢复它以提供更好,更清洁的方式来做到这一点。

至少从 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)
于 2017-08-23T07:00:00.273 回答