简体   繁体   English

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

[英]How to extend manager method in django?

I would like to extend _filter_or_exclude method on my manager, but for some reason, the method is never called. 我想在我的管理器上扩展_filter_or_exclude方法,但是由于某些原因,从未调用该方法。

What I want to achieve is to implicitly filter models, which don't have field deleted = 0 (with all get() and filter() and all() and exclude() and possibly other methods) 我要实现的是隐式过滤模型,该模型没有将字段删除= 0(使用所有get()filter()以及all()exclude()以及可能的其他方法)

My models 我的模特

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):

    ...

Now when I run 现在当我跑步

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

The extended method _filter_or_exclude is not called on the custom manager, but on a default one. 扩展方法_filter_or_exclude不在自定义管理器上调用,而是在默认管理器上调用。

What am I doing wrong? 我究竟做错了什么?

You can override get_queryset method for manager. 您可以覆盖管理器的get_queryset方法。 And to add all instances including deleted ones, you can add another method. 要添加所有实例(包括已删除的实例),可以添加另一种方法。 like this. 像这样。

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()

And use it like this. 并像这样使用它。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM