Django 管理器链接

2024-05-23

我想知道是否有可能(如果可以的话,如何)将多个管理器链接在一起以生成受两个单独管理器影响的查询集。我将解释我正在研究的具体示例:

我有多个抽象模型类,用于为其他模型提供小型的特定功能。其中两个模型是DeleteMixin 和GlobalMixin。

DeleteMixin 定义如下:

class DeleteMixin(models.Model):
    deleted = models.BooleanField(default=False)
    objects = DeleteManager()

    class Meta:
        abstract = True

    def delete(self):
        self.deleted = True
        self.save()

基本上它提供了一个伪删除(删除标志)而不是实际删除对象。

GlobalMixin 定义如下:

class GlobalMixin(models.Model):
    is_global = models.BooleanField(default=True)

    objects = GlobalManager()

    class Meta:
        abstract = True

它允许将任何对象定义为全局对象或私有对象(例如公共/私有博客文章)。

这两个都有自己的管理器,会影响返回的查询集。我的DeleteManager 过滤查询集以仅返回已删除标志设置为False 的结果,而GlobalManager 过滤查询集以仅返回标记为全局的结果。以下是两者的声明:

class DeleteManager(models.Manager):
    def get_query_set(self):
        return super(DeleteManager, self).get_query_set().filter(deleted=False)

class GlobalManager(models.Manager):
    def globals(self):
        return self.get_query_set().filter(is_global=1)

所需的功能是让模型扩展这两个抽象模型,并授予仅返回未删除和全局结果的能力。我在具有 4 个实例的模型上运行了一个测试用例:一个是全局且未删除的,一个是全局且已删除的,一个是非全局且未删除的,一个是非全局且已删除的。如果我尝试获取这样的结果集:SomeModel.objects.all(),我会得到实例 1 和 3(两个未删除的实例 - 太棒了!)。如果我尝试 SomeModel.objects.globals(),我会收到一条错误,指出 DeleteManager 没有全局变量(假设我的模型声明是这样的:SomeModel(DeleteMixin, GlobalMixin)。如果我颠倒顺序,我不会不会收到错误,但它不会过滤掉已删除的错误)。如果我更改 GlobalMixin 以将 GlobalManager 附加到全局变量而不是对象(因此新命令将是 SomeModel.globals.globals()),我将得到实例 1 和 2(两个全局变量),而我的预期结果是仅获取实例1(全局、未删除的)。

我不确定是否有人遇到过类似的情况并得出了结果。无论是使其在我当前的想法中发挥作用的方法,还是提供我所追求的功能的重新工作,都将非常感激。我知道这篇文章有点啰嗦。如果需要更多解释,我很乐意提供。

Edit:

我在下面发布了我用于解决这个特定问题的最终解决方案。它基于 Simon 的自定义 QuerySet Manager 的链接。


请参阅 Djangosnippets 上的这段代码:http://djangosnippets.org/snippets/734/ http://djangosnippets.org/snippets/734/

您无需将自定义方法放入管理器中,而是对查询集本身进行子类化。这非常简单并且运行完美。我遇到的唯一问题是模型继承,您始终必须在模型子类中定义管理器(只需:子类中的“objects = QuerySetManager()”),即使它们将继承查询集。一旦您使用 QuerySetManager,这将更有意义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django 管理器链接 的相关文章

随机推荐