要求
修改数据库 Django shell 数据级联(一对多) 元信息 定义字段 模型过滤 创建对象4种方式 查询集
过滤器 获取单个对象 字段查询 时间 聚合函数 跨关系查询 F对象 Q对象
学习课程
1.修改数据库
① 在settings中的DATABASES中进行修改
‘ENGINE’: ‘django.db.backends.mysql’, ’NAME‘ : 数据库名字 ’USER‘: 用户名字 ’PASSWORD‘:密码 ’HOST‘: 主机 ’PORT‘: 端口号 注意:引号加不加“”都可以
注意迁移时驱动问题:
mysqlclient:python2, 3 都能直接使用,致命缺点- 对mysql安装有要求,必须指定位置存在配置文件
mysql- python:- python2 支持很好,- python3 不支持。
pymysql:会伪装成mysqlclient和mysql- python,- python2,
python3都支持init中 import pymysql pymysql. install_as_mysqldb( )
2.Django Shell
了解(当项目较大时运行不方便可以使用django shell)
使用:django 终端,python manager. py shell
集成了django环境的python 终端
通常用来调试
from Two. models import Student
students = Student. objects. all ( )
for student in students:
print ( students. name)
3.数据级联
一对多
添加数据时先添加主表的数据,然后再添加从表的数据,
删除数据的时候先删除从表的数据,再删除主表的数据。
dept 部门表:主表
emp 员工表:从表
两张中有级联关系
带主键的表是主表
带外键的表是从表
关联关系放在从表
(团员找班长-- > 快)
sql的优化
一对多模型关系:
class Grade ( models. Model) :
g_name = models. CharField( max_length= 32 )
class Student ( models. Model) :
s_name = models. CharField( max_length= 16 )
s_grade= models. ForeignKey( Grade)
案例:( 1 ) . 多方获取一方,根据学生找班级名字
显性属性:就是你可以在中直接观察到的属性- - - 》通过多方获取一方 那么可以使用多方调用显性属性直接获取一方数据
student = Student. objects. get( pk= 2 )
grade = student. s_grade
return HttpResponse( grade. g_name)
( 2 ) . 一方获取多方,根据班级 找所有的学生
隐性属性:就是我们在类中观察不到的,但是可以使用的属性- - - 》通过一方获取多方 那么可以使用一方数据的隐性属性 获取多方数据
grade = Grade. objects. get( pk= 2 )
students = grade. sutdent_set. all ( )
content = {
'students' : students
}
return render( request, 'students_list.html' , content)
各大框架filter的数据返回类型
# flask(BaseQuery) tornado(Query) django(QuerySet)
django中的filter结果
<QuerySet [<Emp: Emp object>]> 是一个列表
def getDname(rquest):
emp = Emp.objects.filter(name='迪丽热巴')[0]
print(emp.e_dept.name)
# 拿到员工所对应的主表中的部门的名称
return HttpResponse('查询成功')
一对多的查询
# 主表
class Dept ( models. Model) :
name = models. CharField ( max_length= 32 )
# 从表
class Emp ( models. Model) :
name = models. CharField ( max_length= 32 )
e_dept = models. ForeignKey ( Dept)
1. 通过从表查询主表的数据,显性属性
使用从表的对象emp 调用e_dept属性
2. 通过主表查询从表的数据,隐性属性
使用主表的对象dept 调用 emp_set ( 从表的模型的小写_set) 属性
# 通过从表查询主表
def getDname ( rquest) :
emp = Emp. objects. filter ( name= '迪丽热巴' ) [ 0 ]
print ( emp. e_dept. name)
return HttpResponse ( '查询成功' )
# 通过主表查询从表
def getEname ( request) :
dept = Dept. objects. filter ( name= '开发部门' ) [ 0 ]
emps = dept. emp_set. all ( )
for emp in emps:
print ( emp. name)
print ( emp. id)
return HttpResponse ( '查询成功' )
4.元信息
class Meta:指定表名和字段名字
db_table = '表名'
注意:表的字段一般都是下划线 eg:s_name
类的属性一般都是驼峰式 eg: sName
5.定义字段
字段类型:CharField,TextField,IntegerField,FloatField,BooleanField,DecimalField,NullBooleanrField,AutoField,FileField,ImageField
字段约束:max_length,default,unique,index,primary_key,db_column
模型属性类型
定义属性
概述
·django根据属性的类型确定以下信息
·当前选择的数据库支持字段的类型
·渲染管理表单时使用的默认html控件
·在管理站点最低限度的验证
·django会为表增加自动增长的主键列,每个模型只能有一个主键列,
如果使用选项设置某属性为主键列后,
则django不会再生成默认的主键列
·属性命名限制
·遵循标识符规则
·由于django的查询方式,不允许使用连续的下划线
库
·定义属性时,需要字段类型,字段类型被定义在
django. db. models. fields目录下,为了方便使用,
被导入到django. db. models中
·使用方式
·导入from django. db import models
·通过models. Field创建字段类型的对象,赋值给属性
逻辑删除
·对于重要数据都做逻辑删除,不做物理删除,
购物车使用物理删除
实现方法是定义isDelete属性,类型为BooleanField,默认值为False
字段类型
·AutoField(IntegerField的子类 6 )
·一个根据实际ID自动增长的IntegerField,
通常不指定如果不指定,一个主键字段将自动添加到模型中
·CharField ( max_length= 字符长度)
·字符串,默认的表单样式是 TextInput
·TextField
·大文本字段,一般超过4000 使用,默认的表单控件是Textarea
·IntegerField
·整数
·DecimalField ( max_digits= None, decimal_places= None)
·使用python的Decimal实例表示的十进制浮点数
银行和金融保险,相关的数据
存一个亿
·参数说明
·DecimalField. max_digits
·位数总数
·DecimalField. decimal_places
·小数点后的数字位数
·FloatField
·用Python的float 实例来表示的浮点数
·BooleanField
有两个选项的时候(男/ 女), 不使用字符串
字符串占用空间大。
·true/ false 字段,此字段的默认表单控制是CheckboxInput
·NullBooleanField
泰国的性别
·支持null、true、false三种值
·DateField ( [ auto_now= False, auto_now_add= False] )
·使用Python的datetime. date实例表示的日期
·参数说明
·DateField. auto_now
·每次保存对象时,自动设置该字段为当前时间,
用于"最后一次修改" 的时间戳,它总是使用当前日期,默认为false
修改一次记录一次
·DateField. auto_now_add(用的多)
·当对象第一次被创建时自动设置当前时间,
用于创建的时间戳,它总是使用当前日期,默认为false
·说明
·该字段默认对应的表单控件是一个TextInput.
在管理员站点添加了一个JavaScript写的日历控件,
和一个“Today"的快捷按钮,包含了一个额外的invalid_date错误消息键
·注意
·auto_now_add, auto_now, and default 这些设置是相互排斥的,不可同时使用。
他们之间的任何组合将会发生错误的结果
·TimeField
·使用Python的datetime. time实例表示的时间,参数同DateField
·DateTimeField
·使用Python的datetime. datetime实例表示的日期和时间,参数同DateField
·FileField
·一个上传文件的字段
·ImageField
·继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
上两个字段依赖pillow
字段选项
·概述
·通过字段选项,可以实现对字段的约束
·在字段对象时通过关键字参数指定
·null
·如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False
·blank
·如果为True,则该字段允许为空白,默认值是 False
·注意
·null是数据库范畴的概念,blank是表单验证证范畴的
·db_column
·字段的名称,如果未指定,则使用属性的名称
·db_index
·若值为 True, 则在表中会为此字段创建索引
·default
·默认值
·primary_key
·若为 True, 则该字段会成为模型的主键字段
·unique
·如果为 True, 这个字段在表中必须有唯一值
关系
·分类
·ForeignKey:一对多,将字段定义在多的端中
·ManyToManyField:多对多,将字段定义在两端中
·OneToOneField:一对一,将字段定义在任意一端中
·用一访问多
·格式
·对象. 模型类小写_set
·示例
grade. students_set
·用一访问一
·格式
·对象. 模型类小写
·示例
·grade. students
·访问id
·格式
·对象. 属性_id
·示例
·student. sgrade_id
6.模型过滤(查询)
Django默认通过模型的objects对象实现模型数据查询。
Django有两种过滤器用于筛选记录:
filter : 返回符合筛选条件的数据集
exclude : 返回不符合筛选条件的数据集
链式调用:
多个filter 和exclude可以连接在一起查询
Person. objects. filter ( ) . filter ( ) . xxxx. exclude( ) . exclude( ) . yyyy
Person. objects. filter ( p_age__gt= 50 ) . filter ( p_age__lt= 80 ) 注意数据类型(Queryset)
Person. objects. exclude( p_age__gt= 50 )
Person. objects. filter ( p_age__in= [ 50 , 60 , 61 ] )
7.创建对象的方式
创建对象的方式
(1)创建对象1 常用
person = Person() person.p_name='zs' person.p_age=18
(2)创建对象2
直接实例化对象,设置属性
创建对象,传入属性
使用person = Model.objects.create(p_name='zs',p_age=18)
person.save()
自己封装类方法创建
在Manager中封装方法创建
(3)创建对象3
person = Person(p_age=18)
(4)创建对象4
注意:__init__已经在父类models.Model中使用,在自定义的模型中无法使用
在模型类中增加类方法去创建对象
@classmethod
def create(cls,p_name,p_age=100):
return cls(p_name=p_name,p_age=p_age)
person = Person.create('zs')
8.查询集
概念:查询集表示从数据库获取的对象集合,查询集可以有多个过滤器。
过滤器:过滤器就是一个函数,基于所给的参数限制查询集结果,返回查询集的方法称为过滤器。
查询经过过滤器筛选后返回新的查询集,所以可以写成链式调用。
获取查询结果集 QuerySet
all
模型.objects.all()
filter
模型.objects.filter()
exclude
模型.objects.exclude()
order_by
persons= Person.objects.order_by('id')
默认是根据id排序
注意要写的是模型的属性
values
persons= Person.objects.order_by('id') persons.values()
注意方法的返回值类型
切片
限制查询集,可以使用下标的方法进行限制
左闭右开区间
不支持负数
下标没有负数
实际上相当于 limit offset
studentList = Student.objects.all()[0:5]
第一个参数是offset 第二个参数是limit
懒查询/缓存集
查询集的缓存:每个查询集都包含一个缓存,来最小化对数据库的访问
在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生数据缓存,django会将查询出来的数据做 一个缓存,并返回查询结果,以后的查询直接使用查询集的缓存。
- 都不会真正的去查询数据库
- 懒查询
- 只有我们在迭代结果集,或者获取单个对象属性的时候,它才会去查询数据
- 为了优化我们结果和查询
获取单个对象:
get
不存在会抛异常 DoesNotExist
存在多于一个 MultipleObjectsReturned
使用这个函数 记得捕获异常
last
返回查询集种的最后一个对象
first
需要主动进行排序
persons=Person.objects.all().first()
内置函数:框架自己封装得方法 帮助我们来处理业务逻辑
count
返回当前查询集中的对象个数
eg:登陆
exists
判断查询集中是否有数据,如果有数据返回True没有反之
字段查询:
对sql中where的实现,作为方法filter(),exclude(),get()的参数
语法:属性名称__比较运算符=值
Person.objects.filter(p_age__gt=18)
条件
属性__操作符=临界值
gt
great than
gte
great than equals
lt
less than
lte
less than equals
gt,gte,lt,lte:大于,大于等于,小于小于等于filter(sage__gt=30)
in
in:是否包含在范围内,filter(pk__in=[2,4,6,8])
单引号可以使用
exact*******
exact:判断,大小写不敏感,filter(isDelete = False)
startswtith
类似于 模糊查询 like
endswith
以 xx 结束 也是like
contains
contains:是否包含,大小写敏感,filter(sname__contains='赵')
isnull,isnotnull
isnull,isnotnull:是否为空,filter(sname__isnull=False)
ignore 忽略大小写
iexact********************
icontains
istartswith
iendswith
以上四个在运算符前加上 i(ignore)就不区分大小写了 iexact...
时间
models.DateTimeField(auto_now_add=True)
year
month 会出现时区问题 需要在settings中的USE-TZ中设置为 False
day
week_day
hour
minute
second
orders = Order.objects.filter(o_time__month=9)
有坑:时区问题
关闭django中自定义的时区
USE-TZ=False
在数据库中创建对应的时区表
注意:mysql oracle中所说的聚合函数 多行函数 组函数 都是一个东西 max min avg sum count
聚合函数
模型:
class Customer(models.Model):
c_name = models.CharField(max_length=16)
c_cost = models.IntegerField(default=10)
使用:
使用aggregate()函数返回聚合函数的值
Avg:平均值
Count:数量
Max:最大
Min:最小
Sum:求和
eg:Student.objects.aggregate(Max('age'))
跨关系查询:
模型:
class Grade(models.Model):
g_name = models.CharField(max_length=16)
class Student(models.Model):
s_name = models.CharField(max_length=16)
s_grade = models.ForeignKey(Grade)
使用:
模型类名__属性名__比较运算符,实际上就是处理的数据库中的join
Grade ---g_name Student---》s_name s_grade(外键)
gf = Student.objects.filter(name='凤姐')
print(gf[0].s_grade.name)
grades = Grade.objects.filter(student__s_name='Jack')
查询jack所在的班级
F对象 eg:常适用于表内属性的值的比较
模型:
class Company(models.Model):
c_name = models.CharField(max_length=16)
c_gril_num = models.IntegerField(default=5)
c_boy_num = models.IntegerField(default=3)
F:
获取字段信息,通常用在模型的自我属性比较,支持算术运算
eg:男生比女生少的公司
companies = Company.objects.filter(c_boy_num__lt=F('c_gril_num'))
eg:女生比男生多15个人
companies = Company.objects.filter(c_boy_num__lt=F('c_gril_num')-15)
Q对象 eg:常适用于逻辑运算 与或或
年龄小于25:
Student.objects.filter(Q(sage__lt=25))
eg:男生人数多余5 女生人数多于10个:
companies = Company.objects.filter(c_boy_num__gt=1).filter(c_gril_num__gt=5)
companies = Company.objects.filter(Q(c_boy_num__gt=5) | Q(c_gril_num__gt=10))
支持逻辑运算:
与或非
&
|
~
年龄大于等于的:
Student.objects.filter(~Q(sage__lt=25))
定义属性
定义属性
get- - - > < class 'Count.models.Account' >
得到模型对象,有save属性,获取一条数据
filter - - - > < class 'django.db.models.query.QuerySet' >
得到的是查询集合,queryset没有save属性,获取所有数据
概述
·django根据属性的类型确定以下信息
·当前选择的数据库支持字段的类型
·渲染管理表单时使用的默认html控件
·在管理站点最低限度的验证
·django会为表增加自动增长的主键列,每个模型只能有一个主键列,
如果使用选项设置某属性为主键列后,
则django不会再生成默认的主键列
·属性命名限制
·遵循标识符规则
·由于django的查询方式,不允许使用连续的下划线
库
·定义属性时,需要字段类型,字段类型被定义在
django. db. models. fields目录下,为了方便使用,
被导入到django. db. models中
·使用方式
·导入from django. db import models
·通过models. Field创建字段类型的对象,赋值给属性
逻辑删除
·对于重要数据都做逻辑删除,不做物理删除,
实现方法是定义isDelete属性,类型为BooleanField,默认值为False
字段类型
·AutoField
·一个根据实际ID自动增长的IntegerField,
通常不指定如果不指定,一个主键字段将自动添加到模型中
·CharField( max_length= 字符长度)
·字符串,默认的表单样式是 TextInput
·TextField
·大文本字段,一般超过4000 使用,默认的表单控件是Textarea
·IntegerField
·整数
·DecimalField( max_digits= None , decimal_places= None )
·使用python的Decimal实例表示的十进制浮点数
·参数说明
·DecimalField. max_digits
·位数总数
·DecimalField. decimal_places
·小数点后的数字位数
·FloatField
·用Python的float 实例来表示的浮点数
·BooleanField
·true/ false 字段,此字段的默认表单控制是CheckboxInput
·NullBooleanField
·支持null、true、false三种值
·DateField( [ auto_now= False , auto_now_add= False ] )
·使用Python的datetime. date实例表示的日期
·参数说明
·DateField. auto_now
·每次保存对象时,自动设置该字段为当前时间,
用于"最后一次修改" 的时间戳,它总是使用当前日期,默认为false
·DateField. auto_now_add
·当对象第一次被创建时自动设置当前时间,
用于创建的时间戳,它总是使用当前日期,默认为false
·说明
·该字段默认对应的表单控件是一个TextInput.
在管理员站点添加了一个JavaScript写的日历控件,
和一个“Today"的快捷按钮,包含了一个额外的invalid_date错误消息键
·注意
·auto_now_add, auto_now, and default 这些设置是相互排斥的,
他们之间的任何组合将会发生错误的结果
·TimeField
·使用Python的datetime. time实例表示的时间,参数同DateField
·DateTimeField
·使用Python的datetime. datetime实例表示的日期和时间,参数同DateField
·FileField
·一个上传文件的字段
·ImageField
·继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
字段选项
·概述
·通过字段选项,可以实现对字段的约束
·在字段对象时通过关键字参数指定
·null
·如果为True ,Django 将空值以NULL 存储到数据库中,默认值是 False
·blank
·如果为True ,则该字段允许为空白,默认值是 False
·注意
·null是数据库范畴的概念,blank是表单验证证范畴的
·db_column
·字段的名称,如果未指定,则使用属性的名称
·db_index
·若值为 True , 则在表中会为此字段创建索引
·default
·默认值
·primary_key
·若为 True , 则该字段会成为模型的主键字段
·unique
·如果为 True , 这个字段在表中必须有唯一值
关系
·分类
·ForeignKey:一对多,将字段定义在多的端中
·ManyToManyField:多对多,将字段定义在两端中
·OneToOneField:一对一,将字段定义在任意一端中
·用一访问多
·格式
·对象. 模型类小写_set
·示例
grade. students_set
·用一访问一
·格式
·对象. 模型类小写
·示例
·grade. students
·访问id
·格式
·对象. 属性_id
·示例
·student. sgrade_id
总结
项目和app的生成
django- admin startproject Demo
django- admin startapp App / python manager. py startapp App
数据库的表的生成和数据迁移
python manager.py makemigrations
python manager.py migrate