Skip to content

ORM模型

ORM, 全称 Object Relational Mapping ,即对象关系映射, 是Django框架的核心组件之一,它提供了一种高级的Pythonic方式来与数据库交互,而不需要直接编写SQL语句。使用 ORM 有以下优点:

  • 开发效率高:减少SQL编写,快速构建数据层
  • 安全性:自动防止SQL注入
  • 可维护性:集中管理数据模型
  • 灵活性:支持多种数据库后端,易于迁移

准备工作

在使用Django ORM之前,需要确保以下准备工作已完成:

  1. 安装数据库驱动
    bash
    pip install pymysql
  2. 配置数据库(以MySQL为例)
    python
    # project_demo/settings.py
    DATABASES = {
      'default': {
        # 数据库引擎(是mysql还是oracle等)
        'ENGINE': 'django.db.backends.mysql',
        # 数据库名
        'NAME': 'database_demo ',
        # 连接数据库的用户名
        'USER': 'root',
        # 连接数据库的密码
        'PASSWORD': '123456qwe',
        # 数据库的主机地址
        'HOST': '127.0.0.1',
        # 数据库的端口号
        'PORT': '3306',
      }
    }

创建ORM模型

在Django中,ORM模型通常定义在APP的 models.py 文件中。每个模型对应数据库中的一张表,类的属性对应表中的字段。

python
from django.db import models

class Book(models.Model):
  # 字符串类型,最大长度100字符
  title = models.CharField(max_length=100)
  # 字符串类型,最大长度50字符
  author = models.CharField(max_length=50)
  # 日期类型(默认为当前日期)
  published_date = models.DateField(auto_now_add=True)
  # 小数类型,最多5位数,小数点后2位
  price = models.DecimalField(max_digits=5, decimal_places=2)  

  def __str__(self):
      return self.title  # 返回书名作为字符串表示

常用字段类型

字符串相关

  • CharField
    models.CharField(max_length=100)
    用于存储短文本,必须指定max_length
  • TextField
    models.TextField()
    用于存储长文本,不需要指定max_length
  • EmailField
    models.EmailField(max_length=254)
    专门用于存储电子邮件地址,会自动验证格式
  • URLField
    models.URLField(max_length=200)
    用于存储URL地址,会自动验证格式

数字相关

  • IntegerField
    models.IntegerField()
    用于存储整数,范围 -21474836482147483647
  • PositiveIntegerField
    models.PositiveIntegerField()
    用于存储非负整数,范围 02147483647
  • smallIntegerField
    models.SmallIntegerField()
    用于存储小整数,范围 -3276832767
  • BigIntegerField
    models.BigIntegerField()
    用于存储大整数,范围 -92233720368547758089223372036854775807
  • DecimalField
    models.DecimalField(max_digits=5, decimal_places=2)
    用于存储精确的小数,max_digits表示总位数,decimal_places表示小数点后位数
  • FloatField
    models.FloatField()
    用于存储浮点数

日期和时间相关

  • DateField
    models.DateField(auto_now=True, auto_now_add=True)
    用于存储日期(年月日)
    auto_now_add=True: 创建时自动设置为当前日期
    auto_now=True: 每次保存时自动更新为当前日期
  • DateTimeField
    models.DateTimeField(auto_now=False, auto_now_add=False)
    用于存储日期和时间(年月日时分秒)
  • TimeField
    models.TimeField()
    只存储时间(时分秒)

布尔类型相关

  • BollanField
    models.BooleanField(default=False)
    用于存储布尔值(True/False),可以指定默认值
  • NullBooleanField
    models.NullBooleanField(default=None)
    用于存储TrueFalseNone三种状态

关系字段

  • ForeignKey
    models.ForeignKey(related_name='books', on_delete=models.CASCADE)
    用于一对多关系,
    related_name指定反向查询名称,
    on_delete指定删除时的行为
  • ManyToManyField
    models.ManyToManyField(related_name='authors')
    用于多对多关系,
    related_name指定反向查询名称
  • OneToOneField
    models.OneToOneField(related_name='profile', on_delete=models.CASCADE)
    用于一对一关系,类似于ForeignKey,但每个对象只能有一个关联对象

文件相关字段

  • FileField
    models.FileField(upload_to='uploads/')
    用于存储文件,upload_to指定上传目录
  • ImageField
    models.ImageField(upload_to='uploads/')
    用于存储图片,继承自FileField,会自动验证图片格式

其他特殊字段

  • UUIDField
    models.UUIDField(default=uuid.uuid4, editable=False)
    用于存储UUID,通常用于唯一标识符
  • SlugField
    models.SlugField(max_length=50, unique=True)
    用于存储URL友好的字符串,通常用于SEO优化
  • BinaryField
    models.BinaryField()
    用于存储二进制数据
  • JSONField
    models.JSONField()
    用于存储JSON格式数据,支持多种数据库后端

常用字段参数

大多数字段类型都支持以下常用参数:

  • null: 是否允许存储NULL值,默认为False
  • blank: 是否允许字段为空,默认为False
  • default: 字段的默认值
  • unique: 是否唯一,默认为False
  • db_index: 是否创建数据库索引,默认为False
  • verbose_name: 字段的可读名称,通常用于表单显示
  • choices: 可选值列表,通常用于下拉选择框, 如:
    python
    STATUS_CHOICES = [
        ('d', 'Draft'),
        ('p', 'Published'),
        ('a', 'Archived'),
    ]
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='d')

创建和应用迁移

在定义好模型后,需要将模型映射到数据库中:

  1. 创建迁移文件

    bash
    # 将在project/migrations目录下生成迁移文件
    python manage.py makemigrations
  2. 应用迁移

    bash
    # 将迁移文件应用到数据库, 将在数据库中生成相应数据表
    python manage.py migrate
  3. 查看迁移状态

    bash
    python manage.py showmigrations
  4. 回滚迁移

    bash
    # 回滚到指定迁移版本
    python manage.py migrate app_name migration_name

ORM基础操作(增删改查/CRUD)

创建数据(Create)

python
from myapp.models import Book  # 导入模型
# 创建一条新记录
book = Book(title='Python Program', author='Alice', price=39.99)
book.save()  # 保存到数据库

查询数据(Read)

python
  # 获取所有书籍, 返回一个QuerySet对象
  from myapp.models import Book  # 导入模型
  books = Book.objects.all()
  
  # 根据条件查询
  # 模糊查询书名包含'Python'
  python_books = Book.objects.filter(title__contains='Python')  
  
  # 获取单条记录
  first_book = Book.objects.first()  # 获取第一条记录

更新数据(Update)

python
# 更新书籍价格
book = Book.objects.get(id=1)  # 获取id为1的书籍
book.price = 29.99  # 修改价格
book.save()  # 保存修改

删除数据(Delete)

python
# 删除书籍
book = Book.objects.get(id=1)  # 获取id为1的书籍
book.delete()  # 删除记录

模型中的Meta配置

Meta类用于定义模型的元数据,如表名、排序方式等。它是模型类的内部类。

python
class Book(models.Model):
  title = models.CharField(max_length=100)
  author = models.CharField(max_length=50)

  class Meta:
    db_table = 'book'  # 指定数据库表名
    ordering = ['title']  # 默认按书名排序
    verbose_name = '书籍'  # 单数形式的可读名称
    verbose_name_plural = '书籍列表'  # 复数形式的可读名称

外键

在Django ORM中,外键用于建立模型之间的一对多关系。通过外键,可以在一个模型中引用另一个模型的实例。

基本语法

python
from django.db import models

class Author(models.Model):
  name = models.CharField(max_length=50)

class Book(models.Model):
  title = models.CharField(max_length=100)
  author = models.ForeignKey(Author, related_name='books', on_delete=models.CASCADE)  # 外键关联到Author模型

关键参数说明

  • to_field: 指定关联的字段,默认为主键字段
  • related_name: 指定反向查询名称(默认是 <model_name>_set)
    • 如上例中,related_name='books'允许通过author.books_set.all()获取该作者的所有书籍
  • related_query_name: 指定反向过滤器名称
  • on_delete: 指定删除外键关联对象时的行为
    • models.CASCADE: 级联删除(默认值), 如删除作者时,自动删除其所有书籍
    • models.PROTECT: 保护模式, 删除作者时阻止删除其书籍
    • models.SET_NULL: 删除关联对象时,将当前对象的外键字段设置为NULL
    • models.SET_DEFAULT: 删除关联对象时,将当前对象的外键字段设置为默认值
    • models.DO_NOTHING: 什么都不做,可能导致数据不一致
  • db_constraint: 是否在数据库中创建外键约束,默认为True

Last Updated:

Released under the MIT License.