讲师中心 微信公众号

工具推荐

视频效率加速
Laper
Laper

剧本策划到成片协作

updream

一键生成高质量推广成片

立刻MV
立刻MV

低成本歌曲 MV、视频生成

剧云
剧云

中文短剧剧本制作平台

Python Django模型怎么继承_抽象基类abstract=True与多表真实关联继承底层区别解析

秋芳君_1177

秋芳君_1177

发布时间:2026-03-12 10:58:03

|

203人浏览过

|

来源于php中文网

原创

抽象基类(abstract=True)不生成数据库表,仅用于代码复用,其字段被复制到各子类表中;多表继承则为父类建真实表,并通过OneToOneField关联子类。

python django模型怎么继承_抽象基类abstract=true与多表真实关联继承底层区别解析

抽象基类 abstract=True 不会生成数据库表

抽象基类只是代码复用机制,Django 在迁移时完全跳过它,不会为 abstract=True 的模型建表。它的字段会“复制”到每个继承它的具体模型中,就像手动把字段定义粘贴过去一样。

常见错误现象:python manage.py makemigrations 后发现抽象基类没出现在迁移文件里,或执行 python manage.py showmigrations 时看不到对应记录——这正常,不是漏了。

  • 所有子类各自生成独立表,字段重复存在(比如 created_at 在 User 和 Article 表里各有一份)
  • 不能对抽象基类做 MyAbstractModel.objects.all(),会报 AttributeError: type object 'MyAbstractModel' has no attribute 'objects'
  • 如果基类定义了 Meta.ordering 或 Meta.verbose_name,子类默认继承,但可被覆盖

多表继承会为父类建真实表并加 OneToOneField 隐式关联

只要不设 abstract=True,哪怕父类没有显式字段,Django 也会为它单独建一张表,并在子类表里加一个指向它的 OneToOneField(字段名默认是父类小写名,如 place_ptr)。

使用场景:需要复用逻辑 + 共享部分数据(比如多个模型都共用地址、状态、审核人等),且这些字段值在不同子类型间要保持唯一或可统一查询。

立即学习“Python免费学习笔记(深入)”;

Biopython
Biopython

全面的分子生物学工具集。适用于序列操作、文件解析(FASTA/GenBank/PDB)、系统发育分析,以及通过 Bio.Entrez 以编程方式访问 NCBI/

下载
  • 父类实例必须先保存才能创建子类实例,否则抛 ValueError: "Place" needs to have a value for field "id" before this many-to-one relationship can be used.
  • 子类查询时默认走 JOIN(如 Restaurant.objects.select_related('place')),性能敏感时得留意 N+1 或冗余 JOIN
  • 父类表的主键(id)会同时作为子类表的主键和外键,所以 Restaurant.objects.get(id=1) 和 Place.objects.get(id=1) 实际指向同一行物理记录

abstract=True 下字段定义位置影响实际效果

字段写在抽象基类里,还是在子类里重定义,结果可能不同。尤其涉及 related_name、db_column、default 这类参数时,容易误以为“继承了配置”,其实只是文本复制。

例如:抽象基类定义了 status = models.CharField(max_length=20, default='draft'),子类没重写,那每个子表都会带这个字段和默认值;但如果子类自己再写一遍 status,哪怕只改 default,就变成两个独立字段定义,Django 不合并也不警告。

  • related_name 必须显式设置,否则 Django 会自动生成(如 user_set),多个子类继承同一抽象类时若不设,会因反向名冲突导致 makemigrations 失败
  • db_column 在抽象类中指定后,子类表字段名就是那个值;但如果子类又定义同名字段,就覆盖了——不是叠加,是替换
  • 函数默认值(如 default=timezone.now)没问题,但写成 default=timezone.now() 就会在模块加载时执行一次,所有实例共享同一个时间戳

什么时候该选 abstract=True,什么时候该用多表继承

本质区别不在“要不要复用代码”,而在于“要不要共享数据行”。如果字段只是结构相似、语义无关(比如所有模型都要有 created_at),用抽象基类;如果不同模型实例之间存在事实上的父子归属(比如 Restaurant 是一种 Place),且业务上需要按 Place 统一筛选、更新、计数,那就得多表继承。

容易踩的坑:为了图省事把本该是多表继承的场景硬改成抽象基类,结果后面发现没法统一查“所有营业场所”,只能靠 UNION 或应用层聚合,反而更重。

  • 抽象基类适合:审计字段(created_at, updated_by)、软删除标记(is_deleted)、通用状态机字段
  • 多表继承适合:有明确 IS-A 关系的领域模型(Employee / Manager 都是 Person)、需统一管理生命周期的资源(ImageFile, VideoFile 都是 MediaFile)
  • 两者都不能解决“一个子类想继承多个父类”的需求——Django 不支持多重继承,此时只能靠组合(ForeignKey)或第三方库如 django-model-utils 的 InheritanceManager

抽象基类看着轻量,但字段复制多了,迁移和索引维护成本会上升;多表继承看着重,但数据关系清晰,SQL 层面更容易优化。选哪个,取决于你愿不愿意让数据库知道“它们是一家人”。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

讯飞智文

一款面向学习和办公场景的AI文档创作工具,可辅助生成PPT与Word文档,提高资料整理和内容制作效率。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

1911

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

5324

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1849

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

32297

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3807

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3827

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

1263

2023.08.11

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

616

2023.08.10

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

80

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn