Django 使用带有GenericForeignKey()的非默认管理器

Django 使用带有GenericForeignKey()的非默认管理器,django,content-type,generics,Django,Content Type,Generics,我已经更改了GenericForeignKey()可以引用的某些对象上的默认管理器,以便这些对象可能不再显示在该默认管理器中 我还有其他管理者可以找到这些被删除的对象,但我看不出有什么办法可以告诉内容类型框架关于它们的信息。这可能吗 我正在对一些涉及以下经理的模型实施“软删除”: from django.db import models SDManager(models.Manager): def get_query_set(self): return super(S

我已经更改了
GenericForeignKey()
可以引用的某些对象上的默认管理器,以便这些对象可能不再显示在该默认管理器中

我还有其他管理者可以找到这些被删除的对象,但我看不出有什么办法可以告诉内容类型框架关于它们的信息。这可能吗

我正在对一些涉及以下经理的模型实施“软删除”:

from django.db import models

SDManager(models.Manager):

    def get_query_set(self):
        return super(SDManager, self).get_query_set().filter(is_deleted=False)

SDDeletedManager(models.Manager):

    def get_query_set(self):
        return super(SDDeletedManager, self).get_query_set().filter(is_deleted=True)
这允许我执行以下操作:

SDModel(models.Model):
    # ...
    objects = SDManager() # Only non (soft) deleted objects
    all_objects = models.Manager() # The default manager
    deleted_objects = SDDeletedManager() # Only (soft) deleted objects
使用模型中的
GenericForeignKey()
字段引用定义的对象(如
SDModel
)时,它使用
\u default\u manager
属性获取引用,该属性的计算结果为
对象
管理器。这意味着当对象被软删除时,它会释放引用

这是我使用
GenericForeignKey()
字段的主要原因之一。我一直在研究的一个解决方案是实现一个较低版本的内容类型框架,这样我就可以定义自己的
get\u object()
,它使用
all\u objects
管理器来访问references对象

所以我的问题是:

是否可以在现有内容类型框架中使用非默认管理器,以便它查找软删除的对象,或者我必须从头开始重新实现所有需要的部分


我的问题与您的问题完全相同,在深入研究文档/源代码之后,Django似乎没有提供一种现成的方法来实现这一点。我发现的最简单的方法是将
GenericForeignKey
子类化,然后重写
\uuuu get\uuu
方法

这就是它所说的:

rel_obj = ct.get_object_for_this_type(pk=getattr(instance, self.fk_field))
因此,这一行需要重写为:

rel_obj = ct.model_class().all_objects.get(pk=getattr(instance, self.fk_field))

这有点粗糙,但很有效,然后你可以像平常一样充分利用GenericForeignKey的功能。

你可能需要更详细地介绍并发布示例代码。我添加了更多细节,让你更清楚地了解我的困境。如果我遗漏了一些明显的东西,很抱歉,但是你考虑过保留“对象”吗作为默认的models.Manager,将SDManager命名为其他名称?i、 e.交换对象和所有对象的定义?是的,我已经尝试过了,最初这是一个好主意,所有使用
\u default\u manager
的代码都可以通过
所有对象
管理器看到软删除的对象,而定制代码几乎(总是使用对象管理器),但是相关的\u名称字段也可以。因此,使用该方法修补缺陷变得更加复杂。例如,
用户
对象上的任何相关名称字段都可以看到软删除对象。我认为这很像unix权限。将其锁定,只让特定部分看到已删除的对象。你的建议(我已经考虑过)更像是Windows。我相信你可能遇到了这个错误:……基本上,你应该添加到默认管理器类中的“使用\u用于与\u相关的\u”字段不能正常工作。