Вот конкретное решение моей проблемы с использованием пользовательского QuerySetManager от Саймона, с которым Скотт связался.
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
Любой миксин в будущем, который хочет добавить дополнительную функциональность к набору запросов, просто должен расширить BaseMixin (или иметь его где-нибудь в своей иерархии). Каждый раз, когда я пытаюсь отфильтровать установленный запрос, я помещаю его в try-catch на тот случай, если это поле на самом деле не существует (т. Е. Оно не расширяет этот миксин). Глобальный фильтр вызывается с помощью globals (), тогда как фильтр удаления вызывается автоматически (если что-то удаляется, я никогда не хочу, чтобы это отображалось). Использование этой системы допускает следующие типы команд:
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
Следует отметить, что фильтр удаления не влияет на интерфейсы администратора, поскольку диспетчер по умолчанию объявляется первым (делая его по умолчанию). Я не помню, когда они сменили администратора на использование Model._default_manager вместо Model.objects, но все удаленные экземпляры все равно будут отображаться в администраторе (в случае, если вам нужно удалить их).
Для сортировки таблиц вы можете воспользоваться ** tablesorter **