gpt4 book ai didi

python - Django 管理器链接

转载 作者:IT老高 更新时间:2023-10-28 22:09:13 25 4
gpt4 key购买 nike

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

我有多个抽象模型类,用于为其他模型提供小的、特定的功能。其中两个模型是 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()

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

GlobalMixin 是这样定义的:

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

objects = GlobalManager()

class Meta:
abstract = True

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

它们都有自己的管理器,它们会影响返回的查询集。我的 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)。如果我颠倒顺序,我不会t 得到错误,但它不会过滤掉已删除的错误)。如果我将 GlobalMixin 更改为将 GlobalManager 附加到全局变量而不是对象(因此新命令将是 SomeModel.globals.globals()),我会得到实例 1 和 2(两个全局变量),而我的预期结果是只得到实例1(全局的,未删除的)。

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

编辑:

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

最佳答案

在 Djangosnippets 上查看此片段:http://djangosnippets.org/snippets/734/

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

关于python - Django 管理器链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/809210/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com