Django模型实例方法的模式+;等效QuerySet过滤器?

Django模型实例方法的模式+;等效QuerySet过滤器?,django,django-models,django-queryset,Django,Django Models,Django Queryset,这与-,我想定义一个基于QuerySet过滤器的布尔实例方法,或者更好地定义一个明显成对的QuerySet过滤器和布尔实例方法 我已经编写了QuerySet/Manager子类来实现基于文档的各种模型的自定义过滤,例如 class MyModelQuerySet(QuerySet): def visible_to_user(self, user): # Filter logic class MyModelManager(Manager): def get_que

这与-,我想定义一个基于QuerySet过滤器的布尔实例方法,或者更好地定义一个明显成对的QuerySet过滤器和布尔实例方法

我已经编写了QuerySet/Manager子类来实现基于文档的各种模型的自定义过滤,例如

class MyModelQuerySet(QuerySet):
    def visible_to_user(self, user):
        # Filter logic

class MyModelManager(Manager):
    def get_queryset(self):
        return MyModelQuerySet(self.model, using=self._db)
    def visible_to_user(self, user):
        return self.get_queryset().visible_to_user(user)

class MyModel(Model):
    objects = MyModelManager()
我需要的是我可以使用模型实例调用的东西

目前,我正在创建一个仅包含实例的QuerySet,在其上运行筛选器,并查看是否还有剩余内容:

class MyModel(Model):
    objects = MyModelManager()
    def visible_to_user(self, user):
        qs = self.__class__.objects.filter(pk=self.pk)
        if hasattr(qs, 'visible_to_user'):
            return qs.visible_to_user(user).exists()
        return False
这是很好的和通用的(它实际上是在mixin中定义的,所以我可以在我所有的模型中使用它),但它不是很有效——它每次都从数据库中重新检索实例,并且在许多情况下,对于只有一个实例的情况,过滤器逻辑的优化效果很差

简单地在模型上编写一个面向实例的布尔函数就足够容易了,我担心这会很难维护——基本上,对一个版本所做的任何更改都必须反映在另一个版本中,当它们位于完全不同的类中,并且两者之间没有明显的联系时,这就更加困难了

我考虑过的一个选项是将两个函数放在一个mixin中,然后每个组件使用适当的版本:

class VisibleToUserMixin(object):
    def _qs_visible_to_user(self, user):
        # QuerySet logic
    def _instance_visible_to_user(self, user):
        # Instance logic

class MyModelQuerySet(VisibleToUser, QuerySet):
    def visible_to_user(self, user):
        return self._qs_visible_to_user(user)

class MyModel(VisibleToUser, Model):
    def visible_to_user(self, user):
        return self._instance_visible_to_user(user)
这给QuerySet和Model子类增加了一些麻烦,但至少它将所有逻辑保持在一个地方,这样维护人员就可以很容易地看到依赖关系


这里有关于最佳实践的建议吗?

请注意,由于Django 1.7,您不需要定义单独的管理器和queryset-只需定义queryset,并将管理器设置为
MyModelQuerySet.as_manager()
-请参见。谢谢,当我们最终更新到1.7时,这非常有用(我们一直使用Python 2.6,因此Django 1.6)你的过滤器有多复杂?如果它们只是字段/值的东西,那么您可以编写一些东西,在一个方法中将它们转换为一组
filter
参数,然后再编写一些东西,根据模型实例检查相同的字段期望值。在某些情况下,过滤器相当复杂,但我喜欢使用一些通用表示法的想法,这些表示法可以定义一次并在两种方法中适当应用。