Django模型继承与自定义Manager重写filter方法详解

苏见山
苏见山
发布时间:2026-10-13| 5人浏览过
原创

本文介绍如何在Django中通过定义抽象基类实现模型字段复用,并深入解析如何重写Manager类的filter方法以自动过滤is_active字段。通过继承BaseManager并重写核心查询逻辑,开发者可统一数据访问层行为,减少冗余代码,提升代码的Pythonic程度与维护效率。

Django模型继承与自定义Manager基础

Django自定义管理器与模型继承机制

在开发过程中,许多数据库模型需要包含通用的字段,例如用于标识状态或记录时间的字段。为了复用这些公共字段,可以创建一个基础的模型类作为基类。

模型类的继承结构

利用面向对象编程(OOP)的特性,我们可以构建一个基类模型。后续创建的所有具体模型均可继承该类,从而避免在每个模型中重复定义相同的字段,简化代码结构。

抽象基类BaseModel实现


class BaseModel(models.Model):
  is_active = models.BooleanField(default=True)
  create_time = models.DateTimeField()

  class Meta:
   '''
   指定这个类是一个抽象模型类, 这个模型就不会被生成表
   '''
    abstract = True 
  
class ChildModel(BaseModel):
  name = models.CharField(max_length=10)
  age = models.PositiveIntegerField()
    
  class Meta:
    '''
    meta属性可以重写, 不重写的话也会继承基类meta
    '''
    verbose_name = '子模型'

重写Django模型的objects管理器

在使用model.objects.filter()进行查询时,通常希望自动过滤掉is_active为False的记录。如果每次查询都手动添加filter(is_active=True),会导致代码冗余。通过重写filter方法,可以实现自动过滤。以下结合Django源码进行分析。

自定义Manager重写filter逻辑


# 这里源码我就不拉出来了, 我们可以看到django是set了个objects属性, 这个属性对应是一个类的实例对象

class Manager(BaseManager.from_queryset(QuerySet)):
'''
objects 是这个类的实例对象, 这个类我们可以看到他其实继承了 QuerySet类里的方法,
 所以我们可以直接重写个这个类方法,并重写filter方法
'''
  def filter(self, *args, **kwargs):
    """
    我们可以看到 QuerySet里的filter方法和exclude方法都是调用了这个方法, 这个方法的内部实现可
    以自己看一看,就是用的kwargs里的参数
    """
    return self._filter_or_exclude(False, *args, **kwargs)

class MyManager(models.Manager):
  
  def filter(self, *args, **kwargs):
  '''
  源代码的filter函数是有返回值的,所以我们将super出来的结果返回出去,我们只需要在kwargs中增加个参数就行
  '''
    if not kwargs.get('is_active', True): # 如果需要查看所有数据,
      kwargs['is_active'] = False
    return super(AddressManager, self).filter(*args, **kwargs)

# 最后我们在我们的ChildModel下将objects对象赋值为MyManager的实例对象就可以使用了
# 我们可以将这个objects写在基类里面,这样所有的model就可以都会有这个方法,具体怎么使用视情况而定

class ChildModel(models.Model):
  objects = MyManager()

模型类支持多继承,若有特殊需求可进一步查阅文档或搜索相关案例。此处主要引入面向对象的概念,展示如何通过继承框架现有类并重写方法,使代码更加符合Pythonic风格。

Django Model字段属性与选项详解

补充知识:Django Model字段属性与选项配置

常见字段类型包括:

autoField:自动增长的IntegerField,通常不显式指定。若不指定,Django会自动添加一个主键字段。

CharField(max_length=字符长度):用于存储字符串,默认表单控件为TextInput。

TextField:用于存储大文本,通常当内容超过4000字符时使用,默认表单控件为Textarea。

IntegerField:用于存储整数。

DecimalField(max_digits=None, decimal_places=None):使用Python的Decimal实例表示十进制浮点数。

参数说明:DecimalField.max_digits表示总位数,DecimalField.decimal_places表示小数点后的位数。

FloatField:使用Python的float实例表示浮点数。

BooleanField:存储True/False值,默认表单控件为CheckboxInput。

NullBooleanField:支持Null、True、False三种值。

DateField([auto_now=False, auto_now_add=False]):使用Python的datetime.date实例表示日期。

参数说明:DateField.auto_now在每次保存对象时自动设置为当前时间,用于记录“最后一次修改”的时间戳,默认为False。

DateField.auto_now_add

在对象首次创建时自动设置为当前时间,用于记录创建时间戳。

该设置始终使用当前日期,默认为False。

说明:该字段默认对应的表单控件是TextInput。在管理员站点中,会添加一个由JavaScript编写的日历控件和一个“Today”快捷按钮,并包含额外的invalid_date错误消息键。注意:auto_now_add、auto_now和default这些设置是互斥的,任何组合使用都可能导致错误结果。

TimeField:使用Python的datetime.time实例表示时间,参数与DateField相同。

DateTimeField:使用Python的datetime实例表示日期和时间,参数与DateField相同。

FileField:用于存储上传的文件。

ImageField:继承自FileField,并对上传对象进行校验,确保其为有效的图像文件。

字段选项配置

概述:通过字段选项可以对字段进行约束,在字段对象中通过关键字参数指定。

null:若为True,Django将空值以NULL存储在数据库中,默认值为False。

blank:若为True,则该字段允许为空,默认值为False。

注意:null是数据库层面的概念,而blank是表单验证层面的概念。

db_column:指定数据库中的字段名称,若未指定,则使用Python属性的名称。

db_index:若值为True,则在此字段上创建数据库索引。

default:指定字段的默认值。

primary_key:若为True,则该字段成为模型的主键字段。

unique:若为True,则该字段在表中必须具有唯一值。

注意:在生成迁移文件后,如果修改的参数不影响表结构(如default、blank),则无需重新生成迁移文件。

模型关系类型与访问方式

关系类型定义

分类说明:

ForeignKey:一对多关系,字段定义在“多”的一端。

ManyToManyField:多对多关系,字段定义在两端。

OneToOneField:一对一关系,字段定义在任意一端。

(1)用一访问多:格式为对象.模型类小写_set。

示例:grade.students_set。

(2)用一访问一:格式为对象.模型类小写。

示例:grade.studnets。

(3)访问外键ID:格式为对象.属性_id。

例子:btitle = models.CharField(max_length=20,db_column=‘title',unique=‘true')。

以上关于重写Django model下objects模型管理器的内容即为分享的全部,希望能提供参考,欢迎支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。