【问题标题】:How to Add custom manager to third-party app's model如何将自定义管理器添加到第三方应用的模型
【发布时间】:2020-02-09 15:04:56
【问题描述】:

我在所有模型中添加了is_active 字段以添加软删除功能,并添加了用于获取活动对象的自定义管理器

class SoftDeleteManager(models.Manager):
    def get_queryset(self):
        return super(SoftDeleteManager, self).get_queryset().filter(is_active=True)


class Student(models.Model):
    is_active = models.BooleanField(default=True)
    active_objects = SoftDeleteManager()
    objects = models.Manager()

此外,我还想在 auth.User 模型上添加相同的 active_objects 管理器,但由于此模型未在我的代码库中定义,我不知道如何继续。

【问题讨论】:

  • 您应该使用自定义用户模型,即使您不更改模型的任何字段。请参阅here 了解如何执行此操作。希望这不是生产中的应用程序,您仍然可以从自定义用户模型重新开始(在项目中更改用户模型很复杂)。对于其他 3rd 方应用程序,您始终可以子类化模型以将 is_active 字段添加到模型并更改默认管理器或添加额外的管理器。
  • 请注意,您必须小心“重用”User 模型的 is_active 字段来指示软删除。在某些情况下,is_activeFalse,直到用户验证他们的电子邮件地址。或者用户可能由于可疑活动而被暂停,这也是is_active 可能被设置为False 的地方。因此,将其解释为“已删除”可能不是您想要的。
  • @dirkgroten 谢谢,但我正在寻找一个通用的解决方案来向任何 3rd 方应用程序添加自定义管理器。上面的用例只是一个例子。
  • 好吧,User 是一个特例,所以它不是第 3 方应用程序的一个很好的例子。对于任何其他模型,只需 subclass it,如果它没有 is_active 字段(因为您需要添加带有该字段的表)或者如果模型已经有 is_active 字段,请使用 proxy model

标签: django django-managers


【解决方案1】:

假设:您想要软删除没有具有is_active 字段的任何第3 方模型。它不应该是 auth.User 模型,因为那是一种特殊情况。

我首先创建一个抽象模型类来实现软删除行为:

class SoftDeleteModel(models.Model):
    is_active = models.BooleanField(default=True)

    active_objects = SoftDeleteManager()
    objects = models.Manager()

    class Meta:
        abstract = True

现在假设您有一个模型为 Message 的 3rd 方应用,然后在您的应用中,您可以对其进行子类化:

from 3rdparty.models import Message as ExtMessage
from .models import SoftDeleteModel

class Message(SoftDeleteModel, ExtMessage):
    pass

现在您自己的Message 类具有额外字段和active_objects 管理器。您将需要makemigrationsmigrate,因为将为Message 创建一个新表。

【讨论】:

  • 您的解决方案看起来不错,但我正在寻找在第三方应用程序上添加自定义管理器而不在现有模型上添加任何新字段的解决方案。
  • 然后创建一个代理模型并将自定义管理器放在代理模型上。
  • 但是第三方应用程序代码的行为将如何变化?
  • “改变 3rd 方应用代码的行为”是什么意思?在您的问题中,您说您想要的只是一个过滤 is_active 的额外管理器。如果您从代理实例化一个对象,它将表现得像第 3 方模型,但会有额外的管理器。您只需要确保始终在自己的代码中使用代理。
  • 假设,第三方应用程序正在使用默认管理器的方法,并且您已在自定义管理器中覆盖它。当第三方应用程序调用 field._default_manager.some_function 时,它将调用默认函数,而不是你的。这已经在 Django 反序列化代码中完成了,这就是我要问的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
  • 1970-01-01
  • 2016-08-21
  • 2020-03-26
  • 2013-03-08
  • 1970-01-01
  • 2016-06-16
相关资源
最近更新 更多