Django学习篇02-ORM


简介

Django ORM(对象关系映射)是 Django 框架中的一个组件,用于在应用程序和数据库之间进行交互。它提供了一种高级的、Pythonic 的方式来管理数据库,并且屏蔽了底层数据库的具体实现细节,使开发者可以更专注于业务逻辑的编写。

Django ORM 的主要目标是提供一个简单直接的API,通过使用面向对象的方式来操作数据库,避免直接与 SQL 语句打交道。以下是 Django ORM 的一些重要特点:

  1. 对象关系映射:Django ORM 将数据库表映射为 Python 类,将每个表记录映射为类的一个实例。这样,我们可以在代码中操作这些对象,而不需要手动编写 SQL 查询。

  2. 数据库无关性:Django ORM 支持多种数据库后端,包括常见的关系型数据库如 MySQL、SQLite、PostgreSQL,以及非关系型数据库如 MongoDB。这意味着可以在不修改代码的情况下切换数据库。

  3. 模型定义:使用 Django ORM,可以通过定义模型类来描述数据库表结构。模型类是继承自 Django 提供的 models.Model 基类,通过定义类属性来表示表的字段。这样,可以通过模型类来创建、更新、删除、查询数据库中的数据。

  4. 数据库迁移:Django ORM 提供了强大的数据库迁移工具,可以轻松地管理数据库结构的变化。通过迁移文件,可以将模型类的变更同步到数据库中,例如创建表、修改字段、添加关联等。

  5. 查询API:Django ORM 提供了强大而灵活的查询API,使得进行复杂的数据库查询变得简单。可以使用链式调用的方式构建查询,过滤结果、排序、限制数量等。还可以使用聚合函数、联表查询、跨关联查询等高级功能。

  6. 事务支持:Django ORM 支持事务,可以确保数据库操作的一致性和可靠性。可以通过装饰器或上下文管理器的方式来管理事务。

总之,Django ORM 提供了一种优雅、简单的方式来操作数据库,使开发者能够更高效地进行数据库相关的操作。它的特点包括对象关系映射、数据库无关性、模型定义、数据库迁移、强大的查询API和事务支持。

数据库与orm的映射关系

  1. 数据库表与对象:ORM 将数据库中的表映射为应用程序中的对象(通常是类)。每个表对应一个类,表中的每行记录对应类的一个实例。

  2. 表字段与对象属性:数据库表中的字段映射为对象的属性。例如,表的列名可以映射为对象的属性名,表的每行记录对应对象的一个实例,该实例的属性值对应记录中相应字段的值。

  3. 数据类型映射:ORM 将数据库的数据类型映射为适当的编程语言数据类型。例如,数据库的整数类型可能映射为整数数据类型,字符串类型可能映射为字符串数据类型。

  4. 关联关系映射:ORM 还支持映射数据库表之间的关联关系,如一对多、多对多和一对一关系。这些关系通过对象之间的关联属性来表示。例如,ORM 可以使用外键(foreign key)来表示两个表之间的关系。

  5. 数据库操作的方法:ORM 提供了一组方法和API,用于对数据库进行操作。这些方法包括增删改查等常见的数据库操作。

  6. 数据库事务的支持:ORM 还提供了事务的支持,使得对数据库进行操作时可以确保数据的一致性和完整性。

通过 ORM,开发者可以使用面向对象的方式来操作数据库,而无需关注底层数据库的实现细节和编写复杂的 SQL 查询语句。ORM 提供了更高层次的抽象,使得数据库操作更加简单、灵活和易于维护。

models的字段与参数

models的更多字段

  • models.AutoField:自增列= int(11),必须指明primary_key=True

  • models.CharField:指定为字符串字段,必须指明max_length参数。

  • models.BooleanField:布尔类型。

  • models.DateTimeField:日期类型。

  • models.ForeignKey:一对多的外键,第一个参数为父表名(子应用名.父表model类名),第二个参数为on_delete(级联关系)。

  • models.OneToOneField:一对一的外键,第一个参数为父表名(子应用名.父表model类名),第二个参数为on_delete(级联关系)。

  • models.ManyToManyField:多对多的外键,第一个参数为父表名(子应用名.父表model类名)。

models的更多参数

models.py文件中添加数据字段有一些参数,我们在此说明一下这些常用参数的意义。

  • primary_key=True:定义该字段为主键,默认为False,如果定义了一个字段为True,那么就不会自动生成id字段。

  • max_length:指定字段的最大长度,CharField必须得设置max_length参数。

  • verbose_namehelp_text:指定中文的描述,在admin后台站点以及在接口文档平台中会使用到。

  • unique=True:设置唯一约束,数据库中该字段不允许重复,默认为False。

  • default:指定当前字段的默认值。

  • null=True:指定当前字段允许保持null空值,默认为False。

  • blank=True:指定前端在创建数据时允许不输入,默认为False。

  • choices=set:指定choices为一个set嵌套set的对象,代表数据库存一个缩写,和前端交互的时候使用全拼,类似一个缩写字典查询。set的例子:GENDER_CHOICE =((u’M’, u’Male’),(u’F’, u’Female’),)

  • auto_now_add=True:DateTimeField的参数,把创建这条数据的时间作为该字段的时间,,只修改一次。默认为False。

  • auto_now=True:DateTimeField的参数,更新这条数据时,把更新时间作为该字段的时间,只要修改就更新。默认为False。

  • on_delete:级联关系。

    • on_delete=models.CASCADE:当父表数据删除之后,对应的从表数据会被自动删除。

    • on_delete=models.SET_NULL:当父表数据删除之后,对应的从表数据的外键字段会被自动设置为null。

    • on_delete=models.PROTECT:当父表数据删除时,如果存在对应的从表数据,那么会抛出异常。

    • on_delete=models.SET_DEFAULT, default='':父表数据删除之后,对应的从表数据的外键字段会被自动设置为default参数指定的值

  • related_name='interfaces':用于设置父表模型对象获取从表数据时,使用的属性名称

数据库的操作流程(mysql举例)

创建数据库

orm无法创建库 需要自己提前创建好

要创建一个数据库,可以使用数据库管理系统(如MySQL)提供的工具或命令行来执行创建数据库的操作。下面以MySQL为例,介绍如何创建数据库。

  1. 使用 MySQL 命令行登录到 MySQL 服务器:打开终端或命令提示符,输入以下命令并按回车键:

    mysql -u your_username -p

    其中,your_username 是你的 MySQL 用户名。然后会提示输入密码,输入密码后按回车键登录。

  2. 创建数据库:在 MySQL 命令行中,输入以下命令并按回车键:

    CREATE DATABASE your_database_name
        CHARACTER SET utf8mb4
        COLLATE utf8mb4_unicode_ci;

    其中,your_database_name 是你想要创建的数据库的名称。执行该命令后,MySQL 将创建一个新的数据库。

  3. 退出 MySQL 命令行:输入 exit 命令并按回车键退出 MySQL 命令行。

完成以上步骤后,你已成功创建了一个 MySQL 数据库。接下来可以使用 Django 来连接该数据库并进行操作。

Django连接mysql数据库

在 Django 中连接 MySQL 数据库,你需要进行以下配置:

  1. 打开 Django 项目的配置文件 settings.py

  2. DATABASES 配置项中,配置 MySQL 数据库连接信息,示例如下:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'your_database_name',
            'USER': 'your_mysql_username',
            'PASSWORD': 'your_mysql_password',
            'HOST': 'localhost',
            'PORT': '3306',
        }
    }

    其中,your_database_name 是你创建的 MySQL 数据库的名称,your_mysql_usernameyour_mysql_password 是连接 MySQL 的用户名和密码。如果 MySQL 服务器不在本地(如在远程服务器上),需要相应地配置 HOSTPORT

  3. 保存配置文件并退出。

完成以上配置后,你可以在 Django 项目中使用数据库了。Django ORM 将会自动与 MySQL 数据库建立连接,并可以使用模型类来操作数据库表。

创建对应的表

强调:只要在models.py中改动了与数据库相关的代码 就必须要重新执行迁移命令

在 Django 项目中的应用程序目录下的 models.py 文件中,定义你的模型类:

  1. 必须继承Model或者Model子类

  2. 一个ORM模型类就对应了一个数据库中的一张表

  3. 在ORM模型类中定义类属性,并且类属性必须是Field的子类,与数据表中的字段对应

  4. CharField类与mysql中的varchar对应,并且必须得指定max_length参数(指定当前字段的最大字节数)

  5. IntegerField类与mysql中integer对应为整型

  6. ORM模型类会自动创建一个名为id的自增主键(非空、唯一),且为integer类型

  7. 如果ORM模型类中某个字段指定了primary_key=True,那么ORM框架就不会自动生成名称为id的自增主键

  8. 会把指定了primary_key=True的字段作为主键

  9. 创建的ORM模型类中字段默认primary_key=False,为非主键字段

  10. verbose_name和help_text指定当前字段的描述信息,一般在api接口文档平台、后台管理站点、前端渲染的表单中会显示

    • verbose_name主要用于提供字段的人类可读名称,改善字段的显示效果。

    • help_text则用于提供字段的额外说明或帮助信息,增加字段的可理解性。

  11. 使用unique=True为当前字段指定唯一约束,默认创建的ORM模型类字段unique=False(可重复)

  12. 使用null=True,指定当前字段在数据库中是否可以存储NULL值,默认该字段在数据库中必须有一个值

  13. 使用default=True,为当前字段指定默认值,指定默认值之后,前端创建数据时,如果不指定该字段,那么会自动将默认值作为当前字段的值

  14. 使用blank=True,指定前端在创建数据时,可以不用传递该字段(在后面序列化器类中使用),默认前端在创建数据时,必须传递该字段

    • 指定字段在表单验证时是否可以为空,如果blank=True,则该字段在表单验证时允许为空

    • 如果blank=False(默认值),则该字段在表单验证时必须有一个值

  15. 可以为DateTimeField、DateField字段添加auto_now_add、auto_now参数

    • auto_now_add=True指定在创建该记录时,会自动将当前创建的时间作为该字段的值,后续不会变更

    • auto_now=True在每次更新该记录时,会自动将当前更新的时间作为该字段的值,后续只要更新了该记录,都会自动修改

    • auto_now_add和auto_now不能同时指定

from django.db import models

# Create your models here.
# 1.创建数据表People
# 2.创建用户名、年龄、性别字段
#      varchar、integer、bool


class People(models.Model):
    username1 = models.CharField(max_length=20)
    age = models.IntegerField()
    gender = models.BooleanField(default=True)


class Project(models.Model):
    id = models.IntegerField(primary_key=True, verbose_name="id主键", help_text='为id主键字段')

    name = models.CharField(verbose_name='项目名称', help_text='输入项目名称', unique=True,max_length=50)

    leader = models.CharField(verbose_name='项目负责人', help_text='输入项目负责人', max_length=20, null=True)

    is_execute = models.BooleanField(verbose_name='是否启动项目', help_text='请选择是否启动项目',default=True)

    desc = models.TextField(verbose_name='项目描述', help_text='输入项目描述', null=True, blank=True)

    create_time = models.DateTimeField(verbose_name='创建时间', help_text='这是创建时间,会自动设置',auto_now_add=True)

    update_time = models.DateTimeField(verbose_name='修改时间', help_text='这是修改时间,每次数据改变时会自动更新',auto_now=True)

    class Meta:
        db_table = 'tb_project'
        verbose_name = '项目表'
        verbose_name_plural = '项目表'
        ordering = ['id']
        # ordering = ['-id', 'name', '?leader']
        ordering = ['-leader', 'name']

修改数据库表信息

如果不指定默认的表名为‘子应用名_model类名’。
在上面的model类中添加Meta子类,该子类中就可以修改数据表的一些信息。修改完成后需要重新生成并执行迁移脚本才会生效。

class People(models.Model):
	class Meta:
        db_table = 'tb_projects' # 修改表名,如果不指定默认的表名为‘子应用名_model类名’
        verbose_name = '项目表' # 指定创建的数据表中文描述信息
        verbose_name_plural = '项目表' # 指定创建的数据表中文描述信息(复数)
        #abstract = True # 迁移时不需要生成这张表

生成迁移脚本

在 Django 中,python manage.py makemigrations 命令用于为应用程序创建数据库迁移文件。如果你想针对指定的子应用程序创建迁移文件,可以将子应用程序的名称作为参数传递给命令。

以下是使用 python manage.py makemigrations 为特定子应用程序创建迁移文件的示例:

python manage.py makemigrations your_app_name

其中,your_app_name 是你要为其创建迁移文件的子应用程序的名称。确保将 your_app_name 替换为你实际的子应用程序的名称。

当运行上述命令后,Django 将会为该子应用程序检测模型的变更,并生成相应的迁移文件。这些迁移文件记录了数据库结构的变化以及如何将旧版本的数据库迁移到新版本。

请确保在运行 python manage.py makemigrations 命令之前,已经在 Django 项目目录下使用 python manage.py migrate 命令对所有子应用程序进行过初始化迁移操作。这样可以确保每个子应用程序都有一个初始的迁移文件,可以正确地进行进一步的迁移操作。

如果不指定子应用名称,那么会将所有子应用(包括内置)根据models.py文件生成迁移脚本

执行迁移脚本

python manage.py migrate 是 Django 中用于应用数据库迁移的命令。该命令会根据已有的迁移文件,将数据库模式(Schema)更新到最新版本。

当你在 Django 项目中运行 python manage.py migrate 时,它会按照应用程序的顺序执行迁移操作。通常情况下,它会依次执行以下几个步骤:

  1. 检查每个应用程序的迁移文件:Django 会检查每个应用程序的数据库迁移文件,确定哪些迁移文件还未应用到数据库中。

  2. 应用未应用的迁移:Django 会应用那些还未应用的迁移文件,将数据库结构更新到最新版本。

  3. 记录已应用的迁移:Django 会记录已经应用的迁移文件,以便下次运行 migrate 命令时正确地跳过已应用的迁移。

通过运行 python manage.py migrate 命令,Django 将会自动创建数据库表或更新现有的表,以反映你在模型中所做的更改。

请注意,在运行 migrate 命令之前,请确保已经在 settings.py 文件中正确配置了与数据库相关的信息。

查看指定迁移脚本生成的 SQL 语句

使用 python manage.py sqlmigrate 命令可以查看指定迁移脚本生成的 SQL 语句,具体步骤如下:

  1. 确保在命令行中已切换到 Django 项目所在的目录。

  2. 运行以下命令来查看特定迁移脚本生成的 SQL 语句:

python manage.py sqlmigrate your_app migration_name
  • your_app 替换为你实际的应用程序名称。

  • migration_name 替换为要查看的迁移脚本的名称(不包括 .py 后缀)。

例如,假设你有一个名为 books 的应用程序,并且想要查看 0002_add_publisher_field 这个迁移脚本生成的 SQL 语句,那么命令将如下所示:

python manage.py sqlmigrate books 0002_add_publisher_field

运行该命令后,你将在终端中看到生成的 SQL 语句。

请注意,sqlmigrate 命令只返回迁移脚本生成的 SQL 语句,并不会执行实际的数据库操作。如果要执行迁移操作,请使用 migrate 命令。

模型之间的关系

外键分类

当设计 Django 模型时,有三种常用的字段类型用于处理模型之间的关系:ForeignKey、ManyToManyField 和 OneToOneField。下面我将为你提供这三个字段类型的示例和说明

  • ForeignKey(一对多关系): ForeignKey 字段用于建立一对多的关系,其中一个模型实例可以与多个其他模型实例相关联,但每个其他模型实例只能与一个模型实例相关联。

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, on_delete=models.CASCADE)

在上述示例中,每本书(Book 模型实例)都属于一个作者(Author 模型实例),而每个作者可以有多本书。【一对多关系也是建在多的一方】

ForeignKey 对应 MySQL 中的 FOREIGN KEY 约束。这种关系表示一对多关系,其中一个模型实例与多个其他模型实例相关联。在数据库层面,ForeignKey 字段将创建一个包含外键关系的列,并在该列上添加外键约束。

  • ManyToManyField(多对多关系): ManyToManyField 字段用于建立多对多的关系,其中一个模型实例可以与多个其他模型实例相关联,并且每个其他模型实例也可以与多个模型实例相关联。

from django.db import models

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

class Course(models.Model):
    name = models.CharField(max_length=100)
    students = models.ManyToManyField(Student)

在上述示例中,每个课程(Course 模型实例)可以拥有多个学生(Student 模型实例),并且每个学生也可以选修多门课程。

ManyToManyField 对应两个表之间的连接表(也称为关联表)和两个外键约束。在 MySQL 中,使用中间表存储多对多关系。这个中间表具有对两个相关表的外键约束。

  • OneToOneField(一对一关系): OneToOneField 字段用于建立一对一的关系,其中一个模型实例与另一个模型实例之间存在唯一的关联。

from django.db import models

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

class Profile(models.Model):
    person = models.OneToOneField(Person, on_delete=models.CASCADE)
    bio = models.TextField()

在上述示例中,每个人(Person 模型实例)只有一个个人资料(Profile 模型实例),而每个个人资料只与一个人相关联。【一对一关系,建在查询频率较高的表中】

OneToOneField 对应 MySQL 中的 UNIQUEFOREIGN KEY 约束。这种关系表示一对一关系,其中一个模型实例与另一个模型实例之间存在唯一的关联。在数据库层面,OneToOneField 字段将创建一个包含唯一约束和外键约束的列。

以上是 ForeignKeyManyToManyFieldOneToOneField 这三种字段类型的示例及说明。你可以根据具体的需求,在 Django 模型中使用适合的字段类型来建立模型之间的关联关系。

外键选项

外键字段有许多可选参数,用于定义外键的行为和约束。其中最重要的是 on_delete 参数,它指定了当关联对象被删除时外键的行为。

  • models.CASCADE:级联删除。当关联的对象被删除时,外键也会被删除。

  • models.PROTECT:受保护。当关联的对象被删除时,会引发 ProtectedError 异常,阻止删除操作。

  • models.SET_NULL:设置为空。当关联的对象被删除时,外键字段的值将被设置为 NULL

  • models.SET_DEFAULT:设置为默认值。当关联的对象被删除时,外键字段的值将被设置为默认值。

  • models.SET():设置为指定值。当关联的对象被删除时,外键字段的值将被设置为指定的值。

  • models.SET_ON_DELETE:在删除操作上进行设置。当关联的对象被删除时,外键字段的值将根据其定义的 on_delete 参数进行设置(类似于触发器)。

ORM的增删改查

字段的增删改

可以对模型文件中的字段进行修改,然后通过生成迁移文件并执行迁移来实现对字段的增删改操作。Django 的迁移系统会根据你的模型文件的变化自动生成相应的迁移文件。下面是具体的步骤:

  • 修改模型文件:

在你的模型文件中,根据需要对字段进行增删改操作。

from django.db import models

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

例如,你可以将 Book 模型中的 author 字段删除或修改其它字段的属性。

  • 生成迁移文件:

运行以下命令生成迁移文件:

python manage.py makemigrations your_app

Django 将会检测到你对模型文件的修改,并自动生成一个迁移文件。

  • 执行迁移:

运行以下命令来应用迁移并将数据库中的表结构更新为最新状态:

python manage.py migrate your_app

Django 将会执行刚刚生成的迁移文件中的操作,包括增加、删除和修改字段等。

请注意,如果你删除字段或修改字段类型等非可逆操作,可能会导致数据丢失,所以在修改字段之前,建议备份或迁移数据。

或者也可以

  • 要删除字段,需要进行迁移。创建一个新的迁移文件,并在该文件中使用 migrations.RemoveField 操作。

  • 要修改字段,也需要进行迁移。创建一个新的迁移文件,并在该文件中使用 migrations.AlterField 操作。