codecamp

Django4.0 管理器-自定义管理器和模型继承

下面是Django如何处理自定义管理器和模型继承:

  1. 基类的管理器总是被子类以 Python 的普通名称解析顺序继承(子类上的属性会覆盖所有父类上的同名属性;直接父类会覆盖更上一级的,以此类推)。
  2. 如果没有在模型或其父类申明管理器,Django 会自动创建 ​objects ​管理器。
  3. 一个类的默认管理器要么由 ​Meta.default_manager_name​ 指定,要么是模型中申明的第一个管理器,或者是直接父模型的默认管理器。

如果您想通过抽象基类在一组模型上安装自定义管理器,但仍能自定义默认管理器,这些规则提供了必要的灵活性。例如,假设有此基类:

class AbstractBase(models.Model):
    # ...
    objects = CustomManager()

    class Meta:
        abstract = True

如果您在子类中直接使用这一点,如果您在基类中没有声明任何管理器,那么 ​objects将是默认的管理器:

class ChildA(AbstractBase):
    # ...
    # This class has CustomManager as the default manager.
    pass

如果您想继承 ​AbstractBase​,但提供不同的默认管理器,则可以在子类上提供该默认管理器:

class ChildB(AbstractBase):
    # ...
    # An explicit default manager.
    default_manager = OtherManager()

这里的 ​default_manager ​是默认的。 ​objects ​管理器仍然可用,因为它是继承的,但没有被当做默认管理器。
最后,对于这个示例,假设您想要向子类中添加额外的管理器,但是仍然使用来自 ​AbstractBase ​的默认管理器。您不能直接在子类中添加新的管理器,因为这将覆盖默认管理器,并且您还必须显式地申明来自抽象基类的所有管理器。解决方案是将这个管理器放到另一个基类中,并在默认管理器 之后 将其引入继承层次结构:

class ExtraManager(models.Model):
    extra_manager = OtherManager()

    class Meta:
        abstract = True

class ChildC(AbstractBase, ExtraManager):
    # ...
    # Default manager is CustomManager, but OtherManager is
    # also available via the "extra_manager" attribute.
    pass

请注意,虽然可以在抽象模型上定义自定义管理器,但不能使用抽象模型 调用 任何方法。即:

ClassA.objects.do_something()

上述是合法的,但如下会引发一个异常。这是因为管理器意在封装管理映射对象集合的逻辑。因为您不能拥有抽象对象的集合,所以管理抽象对象是没有意义的。如果您有适用于抽象模型的功能,则应该将该功能放在抽象模型的 静态方法 或 类方法 中:

AbstractBase.objects.do_something()


Django4.0 管理器-创建带有QuerySet方法的管理器
Django4.0 管理器-执行关系
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

Django4.0 模型和数据库

Django4.0 处理HTTP请求

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }