<p>下面是使用Scott链接到的Simon定制的QuerySetManager解决我的问题的具体方法。</p>
<pre><code>from django.db import models
from django.contrib import admin
from django.db.models.query import QuerySet
from django.core.exceptions import FieldError
class MixinManager(models.Manager):
def get_query_set(self):
try:
return self.model.MixinQuerySet(self.model).filter(deleted=False)
except FieldError:
return self.model.MixinQuerySet(self.model)
class BaseMixin(models.Model):
admin = models.Manager()
objects = MixinManager()
class MixinQuerySet(QuerySet):
def globals(self):
try:
return self.filter(is_global=True)
except FieldError:
return self.all()
class Meta:
abstract = True
class DeleteMixin(BaseMixin):
deleted = models.BooleanField(default=False)
class Meta:
abstract = True
def delete(self):
self.deleted = True
self.save()
class GlobalMixin(BaseMixin):
is_global = models.BooleanField(default=True)
class Meta:
abstract = True
</code></pre>
<p>将来任何想向查询集添加额外功能的mixin都只需要扩展BaseMixin(或者将其放在其继承结构中的某个位置)。每当我试图过滤设置的查询时,我都会将它包装在一个try catch中,以防该字段实际上不存在(即,它不扩展该mixin)。全局过滤器是使用globals()调用的,而delete过滤器是自动调用的(如果删除了某些内容,我永远不希望它显示出来)。使用此系统可以执行以下类型的命令:</p>
<pre><code>TemporaryModel.objects.all() # If extending DeleteMixin, no deleted instances are returned
TemporaryModel.objects.all().globals() # Filter out the private instances (non-global)
TemporaryModel.objects.filter(...) # Ditto about excluding deleteds
</code></pre>
<p>需要注意的一点是,delete过滤器不会影响管理界面,因为默认管理器首先声明(使其成为默认管理器)。我不记得他们何时将管理员更改为使用Model.\u default\u manager而不是Model.objects,但是任何已删除的实例仍将显示在管理员中(以防您需要取消删除它们)。</p>