如何在Django中扩展管理器方法?

时间:2019-04-07 09:41:15

标签: python django django-queryset

我想在管理器上扩展_filter_or_exclude方法,但由于某种原因,从未调用该方法。

我要实现的是隐式过滤没有删除字段= 0的模型(所有get()filter()以及all()exclude()可能还有其他方法)

我的模特

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


class BaseManager(Manager):

    def _filter_or_exclude(self, *args, get_deleted=False,  **kwargs):
        clone = super()._filter_or_exclude(*args, **kwargs)
        if not get_deleted:
            clone.query.add(Q(deleted=0))
        return clone

# Just for sure, I extended the method on a querySet as well
class BaseQuerySet(QuerySet):

    def _filter_or_exclude(self, *args, get_deleted=False, **kwargs):
        clone = super()._filter_or_exclude(*args, **kwargs)
        if not get_deleted:
            clone.query.add(Q(deleted=0))
        return clone


class BaseModel(Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    deleted = models.IntegerField(default=0)

    ...

    objects = BaseManager.from_queryset(BaseQuerySet)

    class Meta:
        abstract = True

    def delete(self, from_db=False, using=None, keep_parents=False):    
        if from_db:
            super().delete(using, keep_parents)
            return
        self.deleted = 1
        self.save()

class Operation(BaseModel):

    ...

现在我跑步

Operation.objects.get(id="...")

自定义管理器未调用扩展方法_filter_or_exclude,而是默认方法。

我在做什么错了?

1 个答案:

答案 0 :(得分:1)

您可以覆盖管理者的get_queryset方法。要添加所有实例(包括已删除的实例),可以添加另一种方法。这样。

class BaseManager(Manager):
        def get_queryset(self):
            qs = super().get_queryset()
            qs = qs.filter(deleted=1) # or whatever your condition is
            return qs

    def all_objects(self):
        return super().get_queryset()

并像这样使用它。

Model.objects.get() # filtered results
Model.objects.all_objects.get() # include deleted ones.