Django框架--六--数据库

版权声明:转载请标明出处 https://blog.csdn.net/gymaisyl/article/details/84933063

㈠简介:

Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。

Django 为这些数据库提供了统一的调用API。 我们可以根据自己业务需求选择不同的数据库。

MySQL 是 Web 应用中最常用的数据库。本章节我们将以 Mysql 作为实例进行介绍。你可以通过本站的 MySQL 教程 了解更多Mysql的基础知识。

django中内嵌了ORM框架,不需要直接面向数据库编程,而是定义模型类,通过模型类和对象完成数据表的增删改查操作。

使用django进行数据库开发的步骤如下:

  1. 配置数据库连接信息
  2. 在models.py中定义模型类
  3. 迁移
  4. 通过类和对象完成数据增删改查操作

㈡配置:

1. 使用MySQL数据库首先需要安装驱动程序:
ORM框架只能将模型类的操作转换为sql语句,但是不能发送到mysql服务端,所以需要驱动将数据进行发送和接收,
但是,django的ORM框架只能识别 mysqldb这个驱动,但是好巧不巧,这个驱动,只支持python2.x版本的,但是现在基本大部分在使用3.x的所以,我们就安装了PyMySQL这个驱动;

pip install PyMySQL

2. 在Django的工程同名子目录的__init__.py文件中添加如下语句 :
将PyMySQL转为pymysql,作用是让Django的ORM能以mysqldb的方式来调用PyMySQL。

from pymysql import install_as_MySQLdb
install_as_MySQLdb()

3. 修改database

Django中默认使用的数据库是sqlite
在这里插入图片描述

改为:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',  # 数据库主机
        'PORT': 3306,  # 数据库端口号
        'USER': ' username ',  # 数据库用户名
        'PASSWORD': 'password ',  # 数据库用户密码
        'NAME': 'djangotest'  # 数据库名字
    }
}

在mysql中创建数据库:

create database djangotest default charset=utf8;

㈢模型类定义:

  • 模型类被定义在"应用/models.py"文件中。
  • 模型类必须继承自Model类,位于包django.db.models中。

在子应用/models.py中定义一个模型类如下:

# 定义一个演员类
class Actor(models.Model):
    GENDER_CHOICES = (
        (0, 'male'),
        (1, 'female')
    )
    name = models.CharField(max_length=20, verbose_name='名称') 
    gender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')  
    comment = models.CharField(max_length=200, null=True, verbose_name='描述信息') 
    book = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书')  # 外键
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_heros'  # 定义数据库表名
        verbose_name = '演员'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

1) 数据库表名

模型类如果未指明表名,Django默认以 小写app应用名_小写模型类名 为数据库表名。

可通过db_table 指明数据库表名。

2) 关于主键

django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后django不会再创建自动增长的主键列。

默认创建的主键列属性为id,可以使用pk代替,pk全拼为primary key

3) 属性命名限制

  • 不能是python的保留关键字。
  • 不允许使用连续的下划线,这是由django的查询方式决定的。
  • 定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:属性=models.字段类型(选项)

4)字段类型
在这里插入图片描述

5) 选项
null是数据库范畴的概念,blank是表单验证范畴的
在这里插入图片描述

6) 外键

在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:

  • CASCADE 级联,删除主表数据时连通一起删除外键表中数据;
  • PROTECT 保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据;
  • SET_NULL 设置为NULL,仅在该字段null=True允许为null时可用
  • SET_DEFAULT 设置为默认值,仅在该字段设置了默认值时可用
  • DO_NOTHING 不做任何操作,如果数据库前置指明级联性,此选项会抛出IntegrityError异常;
  • SET() 设置为特定值或者调用特定方法如下图

在这里插入图片描述

模型类定义之后,进行数据库迁移,就会在数据库中生成对应的数据表:

python manage.py makemigration
python manage.py migrate

㈣数据库的增删改查:

先定义两个模型类:
在这里插入图片描述
在这里插入图片描述

1.增加

1)save():先创建模型类对象,执行对象的save()方法保存到数据库中;

在这里插入图片描述

2)create:通过模型类.objects.create()保存
在这里插入图片描述

2.查询

2.1基本查询:

  • get 查询单一结果,如果不存在会抛出模型类.DoesNotExist异常。
  • all 查询多个结果。
  • count 查询结果数量。
    在这里插入图片描述

2.2过滤查询:
实现SQL中的where功能,包括

  • filter 过滤出多个结果
  • exclude 排除掉符合条件剩下的结果
  • get 过滤单一结果

对于过滤条件的使用,上述三个方法相同,故仅以filter进行讲解。

过滤条件的表达语法如下:

属性名称__比较运算符=值
属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线

exact:表示判等
contains:是否包含
startswith、endswith:以指定值开头或结尾。
isnull:是否为null。
in:是否包含在范围内。
gt 大于 (greater then)
gte 大于等于 (greater then equal)
lt 小于 (less then)
lte 小于等于 (less then equal)
不等于的运算符,使用exclude()过滤器。
year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。

比如:

Movie.objects.filter(id__in=[1, 3, 5])

2.3:F对象
两个属性之间的比较:使用F对象,被定义在django.db.models中。
比如:查询阅读量大于等于评论量的电影。
在这里插入图片描述

2.4:Q对象
多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字。
Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或。
Q对象前可以使用~操作符,表示非not。

比如:查询观看量大于20,或编号小于3的电影,只能使用Q对象实现

Movie.objects.filter(Q(watch__gt=20) | Q(pk__lt=3))

在这里插入图片描述

比如:查询编号不等于3的电影:

Movie.objects.filter(~Q(pk=3))

在这里插入图片描述

2.5:排序:order_by

Movie.objects.all().order_by('bread')  # 升序
Movie.objects.all().order_by('-bread')  # 降序

2.5:关联查询:

本文案例中,假设电影Movie是一,演员Actor是多;

1)一对多访问语法:一对应的模型类对象.多对应的模型类名小写_set
比如:查询电影对应的演员:

b = Movie.objects.get(id=1)
b.actor_set.all()

2)多对一的访问语法:多对应的模型类对象.多对应的模型类中的关系类属性名
比如:查询某个演员对应是哪个电影

h = Actor.objects.get(id=1)
h.book  # 获取电影movie对象
h.book_id  #获取电影movie对象的id

修改

1)save() :修改模型类对象的属性,然后执行save()方法;
在这里插入图片描述

2)update() :使用模型类.objects.filter().update(),会返回受影响的行数
在这里插入图片描述

删除

1)模型类对象delete

actor= Actor.objects.get(id=13)
actor.delete()

2)模型类.objects.filter().delete()

Actor.objects.filter(id=14).delete()

㈤查询集QuerySet:

1.查询集概念

Django的ORM中存在查询集的概念。

查询集,也称查询结果集、QuerySet,表示从数据库中获取的对象集合。

当调用如下过滤器方法时,Django会返回查询集(而不是简单的列表):

  • all():返回所有数据。
  • filter():返回满足条件的数据。
  • exclude():返回满足条件之外的数据。
  • order_by():对结果进行排序。

从SQL的角度讲,查询集与select语句等价,过滤器像where、limit、order by子句。

判断某一个查询集中是否有数据:

exists():判断查询集中是否有数据,如果有则返回True,没有则返回False。

2.查询集特性

1)惰性执行
创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用;

例如,当执行如下语句时,并未进行数据库查询,只是创建了一个查询集qs:

qs = Movie.objects.all()

继续执行遍历迭代操作后,才真正的进行了数据库的查询

for actor in qs:
    print(actor .btitle)

2)缓存
使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。

3.限制查询集

可以对查询集进行取下标或切片操作,等同于sql中的limit和offset子句。

注意:不支持负数索引

对查询集进行切片后返回一个新的查询集,不会立即执行查询。

如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发IndexError异常,[0:1].get()如果没有数据引发DoesNotExist异常。

示例:获取第1、2项,运行查看。

qs = Actor.objects.all()[0:2]

在这里插入图片描述

㈥自定义管理器Manager:

管理器是Django的模型进行数据库操作的接口,Django应用的每个模型类都拥有至少一个管理器。

我们在通过模型类的objects属性提供的方法操作数据库时,即是在使用一个管理器对象objects。当没有为模型类定义管理器时,Django会为每一个模型类生成一个名为objects的管理器,它是models.Manager类的对象。

注意:一旦为模型类指明自定义的过滤器后,Django不再生成默认管理对象objects

1. 修改原始查询集,重写all()方法。
在这里插入图片描述
2. 在管理器类中补充定义新的方法
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/gymaisyl/article/details/84933063