Django Models详解:数据库模型的核心

在 Django 框架中,models 是整个应用的核心之一。它不仅定义了数据的结构,还负责与数据库进行交互。Django 的 ORM(对象关系映射)使得开发者可以用 Python 代码来操作数据库,而无需直接编写 SQL 语句,从而提升了开发效率和代码可维护性。

本文将详细讲解 Django 的 models 模块,包括字段类型、字段选项、模型关系、查询操作、元类配置等,帮助你全面掌握 Django 模型的使用。


一、什么是 Django Models?

Django 的 models.Model 是一个 Python 类,它对应数据库中的一张表。每个 Model 子类的实例代表数据库中的一行记录,类中的每个属性代表数据库表中的一个字段。

通过 models,你可以:

  • 定义数据表结构(字段、类型、约束)
  • 创建数据库表(通过迁移)
  • 查询、更新、删除数据
  • 建立模型之间的关系(如外键、多对多)

二、创建一个简单的模型

复制代码
# models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    is_published = models.BooleanField(default=True)

    def __str__(self):
        return self.title

字段解释:

|----------------|--------------|-------------|
| 字段名 | 类型 | 说明 |
| title | CharField | 字符串,最大长度100 |
| author | CharField | 作者名 |
| published_date | DateField | 出版日期 |
| is_published | BooleanField | 是否已出版,有默认值 |


三、字段类型详解

Django 提供了丰富的字段类型,以下是常用字段类型:

|-------------------|------------------------------------------|
| 字段类型 | 说明 |
| CharField | 存储短字符串,必须指定 max_length |
| TextField | 存储长文本 |
| IntegerField | 整数 |
| FloatField | 浮点数 |
| BooleanField | 布尔值(True/False) |
| DateField | 日期(YYYY-MM-DD) |
| DateTimeField | 日期时间(YYYY-MM-DD HH:MM[:ss[.uuuuuu]]) |
| EmailField | 邮箱地址,自动验证格式 |
| URLField | URL 地址 |
| FileField | 上传文件 |
| ImageField | 上传图片(继承自 FileField) |
| ForeignKey | 外键,建立一对多关系 |
| ManyToManyField | 多对多关系 |
| OneToOneField | 一对一关系 |


四、字段选项(Field Options)

每个字段都可以设置一些可选参数来控制其行为:

|----------------|------------------------------------------|
| 选项名 | 说明 |
| null | 如果为 True ,则数据库中该字段允许为 NULL,默认为 False |
| blank | 如果为 True ,则字段可以为空(用于表单验证),默认为 False |
| default | 字段的默认值 |
| primary_key | 如果为 True ,则该字段为主键,默认会自动生成一个 id 主键 |
| unique | 如果为 True ,则字段值必须唯一 |
| verbose_name | 字段的"人类可读"名称,用于管理界面显示 |
| help_text | 表单中显示的帮助文本 |
| choices | 用于限制字段的取值范围,如 ((1, '男'), (2, '女')) |

示例:

复制代码
GENDER_CHOICES = (
    (1, '男'),
    (2, '女'),
)

class Student(models.Model):
    name = models.CharField(max_length=50, verbose_name='姓名')
    gender = models.IntegerField(choices=GENDER_CHOICES, default=1)

五、模型之间的关系

1. 一对一(OneToOneField)

适用于用户与用户资料等关系。

复制代码
class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField()

2. 一对多(ForeignKey)

最常见的一种关系,例如一本书属于一个作者。

复制代码
class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)

注意:on_delete 参数是必须的,用于指定当关联对象被删除时的行为,如 CASCADE(级联删除)、SET_NULL(设为 NULL)等。

3. 多对多(ManyToManyField)

适用于标签、分类等场景。

复制代码
class Tag(models.Model):
    name = models.CharField(max_length=30)

class Article(models.Model):
    title = models.CharField(max_length=100)
    tags = models.ManyToManyField(Tag)

六、Meta 元类配置

通过 class Meta 可以定义模型的元信息,例如数据库表名、排序方式、权限等。

复制代码
class Book(models.Model):
    title = models.CharField(max_length=100)

    class Meta:
        db_table = 'books'  # 自定义数据库表名
        ordering = ['title']  # 默认排序
        verbose_name = '书籍'
        verbose_name_plural = '书籍列表'

七、模型方法

你可以在模型中定义自定义方法,用于封装业务逻辑或数据处理。

复制代码
class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

    def full_name(self):
        return f"{self.first_name} {self.last_name}"

八、查询操作详解

Django 提供了强大的查询 API,可以通过 Model.objects 来进行数据库操作。

1. 基本查询

复制代码
Book.objects.all()  # 获取所有书籍
Book.objects.get(id=1)  # 获取主键为1的书籍(不存在会抛出异常)
Book.objects.filter(title='Django实战')  # 筛选标题为"Django实战"的书籍
Book.objects.exclude(title='Python入门')  # 排除某些记录

2. 链式查询

复制代码
Book.objects.filter(title__icontains='django').order_by('published_date')

3. 聚合查询

复制代码
from django.db.models import Count, Avg

Book.objects.aggregate(Avg('price'))  # 计算平均价格
Book.objects.annotate(count=Count('author'))  # 按作者统计书籍数量

4. 查询条件(Field Lookups)

|---------------|-----------------------------|------------|
| 查询条件 | 示例 | 说明 |
| __exact | title__exact='Django' | 精确匹配 |
| __iexact | title__iexact='django' | 忽略大小写匹配 |
| __contains | title__contains='Django' | 包含字符串 |
| __icontains | title__icontains='django' | 忽略大小写包含 |
| __gt | price__gt=50 | 大于 |
| __gte | price__gte=50 | 大于等于 |
| __lt | price__lt=50 | 小于 |
| __lte | price__lte=50 | 小于等于 |
| __in | id__in=[1, 2, 3] | 在某个列表中 |
| __isnull | name__isnull=True | 判断是否为 NULL |


九、迁移(Migrations)

当你修改了模型后,需要通过迁移来更新数据库结构。

复制代码
# 生成迁移文件
python manage.py makemigrations

# 应用迁移
python manage.py migrate

十、总结

Django 的 models 模块是构建 Web 应用的基础,它不仅简化了数据库操作,还提供了强大的关系映射和查询功能。熟练掌握 models 的使用,可以帮助你快速构建高效、可维护的数据库模型。

推荐学习路径:

  1. 阅读官方文档:Django Models 官方文档
  2. 学习数据库优化技巧(如索引、查询优化)
  3. 掌握模型继承(抽象基类、代理模型)
  4. 学习使用 signals(信号)处理模型事件
  5. 结合 Django Admin 和 DRF(Django REST Framework)使用 models 构建完整应用

参考资料

相关推荐
IMER SIMPLE4 分钟前
人工智能-python-OpenCV图像处理核心技术:梯度计算、边缘检测与轮廓分析详解
人工智能·python·opencv
rookiesx8 分钟前
安装本地python文件到site-packages
开发语言·前端·python
火凤凰--凤凰码路35 分钟前
MySQL 中的“双路排序”与“单路排序”:原理、判别与实战调优
android·数据库·mysql
2301_7644413339 分钟前
储粮温度预测新方案!FEBL模型用代码实现:LSTM+注意力+岭回归的完整流程
python·深度学习·机器学习
叫我:松哥42 分钟前
优秀案例:基于python django的智能家居销售数据采集和分析系统设计与实现,使用混合推荐算法和LSTM算法情感分析
爬虫·python·算法·django·lstm·智能家居·推荐算法
yivifu1 小时前
使用OpenCV做个图片校正工具
python·opencv·计算机视觉
过客随尘1 小时前
Mysql RR事务隔离级别引发的生产Bug,你中招了吗?
后端·mysql
知其然亦知其所以然1 小时前
社招 MySQL 面试官问我:InnoDB 的 4 大特性?我靠这 4 个故事一战封神!
后端·mysql·面试
一个天蝎座 白勺 程序猿1 小时前
Python(32)Python内置函数全解析:30个核心函数的语法、案例与最佳实践
android·开发语言·python
hqxstudying1 小时前
J2EE模式---业务代表模式
java·前端·python·设计模式·java-ee·mvc