###Django 数据库
####1.1 ORM框架
O是object,也就类对象的意思,R是relation,翻译成中⽂是关系,也就是关系数据库中数据表的意思,M是 mapping,是映射的意思。在ORM框架中,它帮我们把类和数据表进⾏了⼀个映射,可以让我们通过类和类对象 就能操作它所对应的表格中的数据。ORM框架还有⼀个功能,它可以根据我们设计的类⾃动帮我们⽣成数据库中 的表格,省去了我们⾃⼰建表的过程。
####1.2django进行数据库开发的步骤
-
配置数据库连接信息
-
在models.py中定义模型类
-
迁移
-
通过类和对象完成数据增删改查操作
#####1.2.1配置
1.安装MySQL数据库pip install PyMySQL
2.第⼆步: 进⾏转换, 让pymysql的内容转换为mysqldb,以便于ORM能够匹配
# 复制下⾯的内容, 拷⻉到django⼯程同名⼦⽬录中的init.py⽂件中
# 例如我们项⽬为:demo,那就拷⻉到demo/demo/init.py中去.
from pymysql import
install_as_MySQLdb install_as_MySQLdb()
3.第三步: 对数据库进⾏配置: 修改数据库的ip地址,端⼝号, ⽤户名等内容
# 这个⽂件在原来的settings.py⽂件中就有, 我们需要⽤下⾯的内容替换原来的内容:
DATABASES = {
'default': {
# 我们这⾥需要把sqlite3修改为mysql
'ENGINE':'django.db.backends.mysql',
'HOST':'127.0.0.1', # 数据库主机
'PORT': 3306, # 数据库端⼝
'USER': 'root', # 数据库⽤户名
'PASSWORD': 'mysql', # 数据库⽤户密码
'NAME': 'django_demo' # 数据库名字
}
}
4.第四步: 修改完成后,就可以创建数据库定义模型类了.
# 图书-英雄"管理为例进⾏演示
# 创建⼦应⽤booktest 在⼦应⽤的
# models.py ⽂件中定义模型类:
# 从django.db中到models from django.db
import models
# 定义图书模型类BookInfo #
# 注意: ⼀定要继承⾃models.Model
class BookInfo(models.Model):
# 这⾥定义的属性对应的都是数据库中的字段:
# 这⾥定义的时候,可以额外增加字段:
# max_length字符串的最⼤⻓度
# verbose_name在admin站点的名称. default默认值.
# models.CharField 这个位置指出了当前字段的类型:
btitle = models.CharField(max_length=20, verbose_name='名称')
bpub_date = models.DateField(verbose_name='发布⽇期')
bread = models.IntegerField(default=0, verbose_name='阅读量')
bcomment = models.IntegerField(default=0, verbose_name='评论量')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
# 该类⽤于指定数据库中的表名.
class Meta:
db_table = 'tb_books'
# 指明数据库表名
verbose_name = '图书'
# 在admin站点中显示的名称
verbose_name_plural = verbose_name
# 显示的复数名称
def __str__(self):
"""定义每个数据对象的显示信息"""
return self.btitle
说明:除⾮我们想要⾃⼰指定⼀个主键,这个时候,我们可以在这个属性的后⾯添加primary_key=true
from django.db import models
#定义英雄模型类HeroInfo
class HeroInfo(models.Model):
# 这个是元组是⼀个可选项,元组中也是元组, 其中:
# 0, 1: 是在数据库中真实存在的值
# 意味着hgender这个字段在数据库中存储的要么是0,要么是1
# male, female: ⽤于显示在admin站点中
# 类似于: verbose_name
GENDER_CHOICES = (
(0, 'male'),
(1, 'female')
)
hname = models.CharField(max_length=20, verbose_name='名称')
# 性别我们使⽤的是类似于枚举类型来做的:
# choices: 可选范围,传⼊的是个元组类型,在上⾯定义的.
hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')
hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息')
# 利⽤ForeignKey这个属性指定hbook这个字段为外键.
# 第⼀个参数: 表示外键关联到书籍表
# 注意: 如果调⽤外键hbook的话: 返回的是book这个模型对象.
hbook = 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.hname
外键
在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引⽤表数据如何处理,在 django.db.models中包含了可选常量:
on_delete有多少个选项呢:
1.CASCADE: 级联,删除主表数据时同时⼀起删除外键表中数据, 级联删除。
2.PROTECT : 保护模式,如果采⽤该选项,删除的时候,会抛出 ProtectedError 错误。阻⽌⽤户的删除.
3.SET_NULL 置空模式,删除的时候,外键字段被设置为空,仅在该字段null=True: 允许为null时可⽤.
4.SET_DEFAULT : 置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上⼀个默认值。
5.SET() ⾃定义⼀个值,该值当然只能是对应的实体了,看⼀下代码:
####1.2.2迁移
第一步:⽣成迁移⽂件
python manage.py makemigrations
第二步:同步到数据库中
python manage.py migrate
第三步:添加测试数据
###1.3 shell工具
1.进入shell
python manage.py shell
2.查看MySQL数据库⽇志
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
把68,69⾏前⾯的#去除,然后保存并使⽤如下命令重启mysql服务。
sudo service mysql restart
使⽤如下命令打开mysql⽇志⽂件
# 可以实时查看数据库的⽇志内容
tail -f /var/log/mysql/mysql.log
####1.4数据库操作
增加数据有两种⽅法:
1. 创建对象添加数据, 然后调⽤ save( ) 保存.
from datetime import date
>>> book = BookInfo(
btitle='⻄游记',
bpub_date=date(1988,1,1),
bread=10,
bcomment=10 )
>>> book.save()
2. 通过模型类的 create( ) 函数保存.
>>> HeroInfo.objects.create(
hname='沙悟净',
hgender=0,
hbook=book )
<HeroInfo: 沙悟净>
查询
1.get 查询单⼀结果,如果不存在会抛出模型类.DoesNotExist异常。
BookInfo.objects.get(btitle='⻄游记')
2.all 查询多个结果
BookInfo.objects.all()
3.count 查询结果数量
BookInfo.objects.count()
过滤查询 -----属性名称__⽐较运算符=值
1.filter 过滤出多个结果
BookInfo.objects.filter(id__exact=1)
BookInfo.objects.filter(id=1)
BookInfo.objects.filter(btitle__contains='传')
BookInfo.objects.filter(btitle__endswith='部')
BookInfo.objects.filter(btitle__isnull=False)
BookInfo.objects.filter(id__in=[1, 3, 5])
BookInfo.objects.filter(id__gt=3)
# year、month、day、week_day、hour、minute、second:对⽇期时间类型的属性进⾏运算
BookInfo.objects.filter(bpub_date__year=1980)
BookInfo.objects.filter(bpub_date__gt=date(1990, 1, 1))
2.exclude 排除掉符合条件剩下的结果
BookInfo.objects.exclude(id=3)
3.get 过滤单⼀结果
F对象-----F(属性名)
from django.db.models import F
BookInfo.objects.filter(bread__gte=F('bcomment'))
BookInfo.objects.filter(bread__gt=F('bcomment') * 2)
Q对象
# Q对象: 用于查询时多个条件之间的逻辑关系 &(且) |(或) ~(非)
from django.db.models import Q
# 1. 查询阅读量大于20,并且编号小于3的图书。
# book3 = BookInfo.objects.filter(bread__gt=20, id__lt=3)
book3 = BookInfo.objects.filter(Q(bread__gt=20)&Q(id__lt=3))
print(book3)
# 2. 查询阅读量大于20,或编号小于3的图书。
book4 = BookInfo.objects.filter(Q(bread__gt=20) | Q(id__lt=3))
print(book4)
# 3. 查询编号不等于3的图书。
book5 = BookInfo.objects.filter(~Q(id=3))
print(book5)
# 聚合: count sum avg max min
# # 1. 查询图书的总阅读量。
# # 2. 查询图书总数。
# # 3. 对所有图书按照阅读量从大到小进行排序。
# '''
from django.db.models import Count, Sum, Avg, Max, Min
# 1. 查询图书的总阅读量。
res1 = BookInfo.objects.aggregate(Sum('bread'))
print(res1)
# 2. 查询图书总数。
res_counut = BookInfo.objects.count()
print(res_counut)
res2 = BookInfo.objects.aggregate(Count('id'))
print(res2)
# 3. 对所有图书按照阅读量从小到大进行排序。
book1 = BookInfo.objects.order_by('bread')
print(book1)
# 4. 对所有图书按照阅读量从大到小进行排序。
book2 = BookInfo.objects.order_by('-bread')
print(book2)