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

时间:2010-03-03 22:59:39

标签: django content-type generics

我更改了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)时,它会使用_default_manager属性来评估objects经理,以获取参考资料。这意味着当软件删除对象时它会丢失引用。

这是我使用GenericForeignKey()字段的主要原因之一。我一直在研究的解决方案是实现较小版本的内容类型框架,以便我可以定义自己的get_object(),它使用all_objects管理器来访问引用对象。

所以我的问题是:

  

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

1 个答案:

答案 0 :(得分:2)

我和你有完全相同的问题,在深入了解文档/源代码后,看起来Django没有提供开箱即用的方法。我发现最简单的方法是继承GenericForeignKey,然后覆盖__get__方法。

The troublesome line就是它所说的:

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))

它有点hackish但它有效,然后你可以像往常那样使用GenericForeignKey的全部功能。

相关问题