第五章 Django连接数据库
1 连接配置
django 连接mysql的配置流程:
-
安装 pymysql pip install pymysql
-
创建数据库用户(有创建数据库权限)
-
创建数据库
-
修改配置settings
-
修改项目文件夹(和settings.py文件所在的目录)下__init__.py 文件
写上:import pymysql pymysql.install_as_MySQLdb()
-
设置时区 TIME_ZONE = 'Asia/ShangHai' # 北京时间
2 django的ORM系统
ORM概念:对象关系映射(Object Relational Mapping,简称ORM)
ORM的优势:不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。
django模型映射关系:
模型类必须都写在app下的models.py文件中。
模型如果需要映射到数据库,所在的app必须被安装.
一个数据表对应一个模型类,表中的字段,对应模型中的类属性.
2 模型的创建与激活
创建模型
每一个模型都是django.db.models.Model的子类
类变量 表示模型中的数据库字段
每一个字段由一个字段类的实例表示
激活模型
项目中注册app
在settings.py中配置DATABASES
运行数据库迁移命令(一定要在项目根目录下)
python mange.py makemigrations teacher # 将模型类映射到数据库(其中teacher为指定映射,不写默认全部映射)
python manage.py migrate # 将映射文件中的映射数据提交到数据库中
打开数据我们能看到创建的以app名_模型名的数据表,而其他的一些表格是django自动生成的.
注意:如果要删除表,那么可以去django模型中注释掉模型类,然后执行映射的命令,不要手动在命令行里面去删除.
4.数据的增删改查
-工具 django shell 调试
python manage.py shell
增
from movie.models import Movie # movie为app名,Movie为模型类
def add_date(request):
# 方法一
movie_1 = Movie(name="情圣", time=2010) # 模型类的实例
movie_1.save()
# 方法二
movie_2 = Movie()
movie_2.name = '毒液'
movie_3.time = 2016
# 方法三
Movie.objects.create(name="贞子", time=2001)
# 方法四
Movie.object.get_or_create(name="赌圣", time=2004)
return HttpResponse('插入数据')
删
def delete_date(request):
# 条件删除
Movie.objects.get(time=2010).delete()
Movie.objects.filter(name="情圣")。delete()
# 全删除
Movie.objects.all().delete()
return HttpResponse('删除成功')
改
def update_date(request):
# 方法一:先查找对象后修改
rs = Movie.objects.get(name="赌圣")
rs.name = '赌圣2'
rs.save()
# 方法二:直接修改
Movie.objects.filter(name="赌圣").update(name="赌圣2")
# 全部修改
Movie.objects.all().update(time=2010)
return HttpResponse('修改成功')
查
all()和filter()方法返回的是QuerySet对象.
get()方式返回的单个对象,如果符合条件的对象有多个,则get报错!
def search_date(request):
# 查询所有数据对象
re = Movie.objects.all()
# 查询一个数据对象
re = Movie.objects.get(time=2001)
# 查询满足条件的对象
re = Movie.objects.filter(name="情圣")
print(re)
return HttpResponse('查询成功')
5 字段的查询
常用的模型字段类型
django中对数据的对数据的定义实质上是类的实例
数据类型对应关系
int >>>>>>>>>>>>>>>>>>> IntegetField 整型,映射到数据库中的int类型。
id = models.IntegerField(primary_key=True, auto_created=True)
varchar >>>>>>>>>>>>>>> CharField 字符类型,映射到数据库中的varchar类型,通过max_length指定最大长度。
name = models.CharField(max_length=20) # 参数类型为char时,必须设置最大长度(max_length)
longtext >>>>>>>>>>>>>>> TextField 文本类型,映射到数据库中的text类型。
date >>>>>>>>>>>>>>>>> DateField 日期类型,没有时间。映射到数据库中是date类型,在使用的时候,可以设置DateField.auto_now每次保存对象时,自动设置该字段为当前时间。设置DateField.auto_now_add当对象第一次被创建时自动设置当前时间。
c_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
datetime >>>>>>>>>>>>>> DateTimeField 日期时间类型。映射到数据库中的是datetime类型,在使用的时候,传递datetime.datetime()进去。
字段的常用参数
primary_key: 指定是否为主键。
unique: 指定是否唯一。
null: 指定是否为空,默认为False。
blank: 等于True时form表单验证时可以为空,默认为False。
default: 设置默认值。
DateField.auto_now: 每次修改都会将当前时间更新进去,只有调用,QuerySet.update方法将不会调用。这个参数只是Date和DateTime以及TimModel.save()方法才会调用e类才有的。
DateField.auto_now_add: 第一次添加进去,都会将当前时间设置进去。以后修改,不会修改这个值
class Music(models.Model):
name = models.CharField(max_length=20)
author = models.CharField(max_length=20)
note = models.TextField()
is_free = models.BooleanField(default=True)
c_time = models.DateField(auto_now_add=True)
u_time = models.DateTimeField(auto_now=True
常用查询
通过模型类上的管理器(模型类.objects)构造QuerySet(数据库中对象的合集:select语句) 注:QuerySet是惰性的
查询语句:QuerySet.query
查询所有数据
Music.objects.all()
查询所有,返回指定字段 注:可进一步进行filter过滤
Music.objects.values('name','c_time') # 返回QuerySet字典
Music.objects。only('name','c_time') # 返回QuerySet列表(一定包含主键)
查询所有,返回除指定字段外的数据(和only相反)
Music.objects.defer('name') # 作用和only相反
查询第一条数据
Music.objects.first()
查询最后一条数据
Music.objects.last() # 默认通过主键排序,也可通过meta设置
根据条件过滤查询(获取过滤后的QuerySet,可以对该对象进行进一步操作)
Music.objects.filter(name='夜曲')
根据条件排除查询(除条件外的数据,用法同filter)
Music.objects.exclude(name='夜曲')
获取一个记录对象(如果结果为多个,则报错)
Music.objects.get(name='夜曲')
对结果排序
Music.objects.order_by('c_time')
Music.objects.order_by('c_time','u_time') # 多条件排序
Music.objects.order_by('-c_time') # 逆序(在条件前加负号)
Music.objects.all()[:5] # 切片
将查询返回的QuerySet中的Model转换为字典
Music.objects.all().values()
获取查询到数据的总数
Music.objects.count()
常用查询条件
exact >>>>>>>> 准确查询
语法 Music.objects.filter(name__exact='夜曲')
exact >>>>>>>> 模糊查询
语法 Music.objects.filter(name__iexact='夜')
contains >>>>>> 包含查询
语法 Music.objects.filter(name__contains='夜')
icontains >>>>>> 不区分大小写查询
语法 Music.objects.filter(name__icontains='夜')
in >>>>>>>>>>>> 范围查询(列表)
语法 Music.objects.filter(name__in=['夜曲', '对不起', '七里香'])
range >>>>>>>>> 范围查询(元祖)
语法 Music.objects.filter(c_time__range=(2001, 2015))
gt >>>>>>>>>>>> 大于
gte >>>>>>>>>>> 大于等于
lt >>>>>>>>>>>>> 小于
lte >>>>>>>>>>>> 小于等于
(i)startswith >>>>>> (忽略大小写)以条件开头
(i)endswith >>>>>>> (忽略大小写)以条件结尾
聚合和分组
聚合
导入聚合方法
from django.db.models import Avg, Min, Sum
通过QuerySet的aggregate
Music.objects.aggregate(time_avg=Avg('time')) #time_avg为自定义,返回字典数据
同类聚合方法
Max >>>>>>>>>>> 最大值
Min >>>>>>>>>>> 最小值
Sum >>>>>>>>>>> 求和
分组
分组一般配合聚合使用
from django.db.models import Count #先分组后聚合
Music.objects.values('c_time').annotate(num=Count('c_time'))
表关系实现
OneToOne
**
student = models.OneToOneField('student', on_delete=models.CASCADE)
OneToMany
在一对多的关系中,在一表中加入外键(foreignkey)(设置可删除,可为空)
grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True)
ManyToMany
多对多关系需要新建表
Student连接Course
class Course(models.Model):
name = models.CharField('课程名称',max_length=20)
student = models.ManyToManyField('Student', through='Enroll')
class Enroll(models.Model): # django会自动添加表
student = models.ForeignKey('Student', on_delete=models.CASCADE)
course = models.ForeignKey('Course', on_delete=models.CASCADE)
pay = models.FloatField('缴费金额', default=0)
c_time = models.DateTimeField('报名时间', auto_now_add=True)
关联表数据操作
正向操作(存在外键控制附表)
s = Student()
s.name('张三') # 新建数据
s.grade = Grade.obejcts.first() # 创建联系 需要先创建grade表
反向操作(被另一个表的外键控制)
g = Grade()
g.name('python') # 新建数据
g.student_set('李四') # 反向联系
跨表查询
规则为(实例__属性)
Course.objects.filter(student__sex=1) # 查询学生中男生选择的课程
Student.objects.filter(course__name='Engish',grade__num__contains='33') # 查询报名了英语课程的33期的学生