O:类和对象
R:关系,关系数据库中的表格
M:映射
Django ORM框架的功能:
a)建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库
b)根据设计的模型类生成数据库中的表格
c)通过方便的配置就可以进行数据库的切换
1、Django数据库配置
MySQL命令回顾:
连接:mysql -uroot -p
create database bj charset='utf8';
django-admin startproject test
python manage.py startapp book
去settings里面注册应用-->Installed apps
配置数据库
test2-->__init__.py
2、重定向
1.设计url,通过浏览器访问http://127.0.0.1:8000/create/时向数据库中新增一条图书信息
2.设计url对应的视图函数create
1 # views.py 2 def create(request): 3 '''新增一本图书''' 4 # 1.创建BookInfo对象 5 b = BookInfo() 6 b.btitle = 'aa' 7 b.bpub_date = date(1990, 1, 1) 8 # 2. 保存进数据库 9 b.save() 10 # 3. 返回应答,让浏览器再访问/index,重定向 11 return HttpResponseRedirect('/index')12 # urls.py
1 # views.py 2 def delete(request, bid): 3 '''删除电击的图书''' 4 # 1.通过bid获取图书对象 5 book = BookInfo.objects.get(id=bid) 6 # 2.删除 7 book.delete() 8 # 3.重定向,让浏览器访问/index 9 return HttpResponseRedirect('/index') #或者使用redirect函数也可 10 11 # urls.py 12 urlpatterns = [ 13 url(r'^delete(d+)$', views.delete), #加括号是为了能把参数传给框架 14 ]
<a href='/create'>新增</a> #/开头
<ul>
{% for book in books %}
<li> {{ book.btitle }}--<a href="/delete{{ book.id }}"> 删除 </a></li>
{% endfor %}
</ul>
页面重定向:服务器不返回页面,而是告诉浏览器再去请求其他的url地址
3、字段属性和选项
模型类属性命名限制:
1,不能是python的保留关键字
2,不允许使用连续的下划线,这是由django的查询方式决定的
3,定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性名=models.字段类型(选项)
字段类型:
使用时需要引入django.db.models包,字段类型如下:
AutoField:自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性
BooleanField:布尔字段,值为True或False
NullBooleanField:支持Null、True、False三种值
CharField(max_length=最大长度):字符串。参数ma'x_length表示最大字符个数
TextField:大文本字段,一般超过4000个字
IntegerField:整数
DecimalField(max_digits=None,decimal_places=None):十进制浮点数。参数max_digits表示总位,参数decimal_places表示小数位数
FloatField(max_digits=None,decimal_places=None):浮点数,参数同DecimalField 保存格式:2*10多少次方 精确度不如DecimalField高
DateField([auto_now=False,auto_now_add=False]):auto_now修改时间戳,表示每次保存对象时,自动设置该字段为当前时间;auto_now_add,自动添加创建时间为当前时间
TimeField:时分秒,参数同上
DateTimeField:年月日时分秒,参数同上
FileField:上传文件字段
ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片
选项:
default:默认值,设置默认值
primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
unique:如果为True,这个字段在表中必须有唯一值,默认值是False
db_index:若值为True,则在表中会为此字段创建索引,默认值是False
db_column:指定字段名字,如果未指定,则使用属性的名称
null:如果为True,表示允许为空,默认值是False
blank:如果为True,则该字段允许为空白,默认值是False
对比:null是数据库范畴的概念,blank是后台管理页面表单验证范畴的,表单可以为空白
当修改模型类之后,如果添加的选项不影响表的结构,则不需要重新做迁移,商品的选项中default和blank不影响表结构
4、查询 通过模型类查询表数据
修改mysql的日志文件:让其产生mysql.log,即是mysql的日志文件,里面记录的对MySQL数据库的操作记录
查询函数:
通过 模型类.objects (Java-->Class) 属性可以调用如下函数,实现对模型类对应的数据表的查询
get-->返回表中满足条件的一条且只能有一条数据;返回值是一个模型类对象;条件查询没有结果或有多个结果时都会抛出异常
all-->返回模型类对应表格中所有数据;返回值QuerySet类型;查询集
filter-->返回满足条件的数据;返回值是QuerySet类型;参数写查询条件
exclude-->返回不满足条件的数据;返回值是QuerySet类型;参数写查询条件
order_by-->对查询结果进行排序;返回值是QuerySet类型;参数中选择根据哪些字段进行排序
filter方法示例:
条件格式:模型类属性名__条件名=值-->适用于get、filter、exclude
a)判等 条件名:exact BookInfo.objects.get(id__exact=1)
b)模糊查询 包含contains endswith startswith BookInfo.objects.filter(btitle__contains=' h ')
c)空查询 isnull BookInfo.objects.filter(btitle__isnull=False)
d)范围查询 in BookInfo.objects.filter(id__in=[1, 3, 5])
e)比较查询 gt大于 lt小于 gte大于等于 lte小于等于 BookInfo.objects.filter(id__gt=3)
f)日期查询 BookInfo.objects.filter(bpub_date__year=1980)
BookInfo.objects.filter(bpub_date__gt=date(1980,1,1))
exclude方法示例:BookInfo.objects.exclude(id=3)
order_by方法示例:
可以指定多个字段进行排序
BookInfo.objects.all().order_by('id')默认升序
BookInfo.objects.all().order_by('-id')降序排序
BookInfo.objects.filter(id__gt=3).order_by('-bread')
QuerySet类型的对象可以继续调用这些方法
F对象:用于类属性之间的比较
from django.db.models import F
BookInfo.objects.filter(bread__gt==F('bcomment'))
BookInfo.objects.filter(bread__gt==F('bcomment')*2)
Q对象:用于查询时条件之间的逻辑关系。 not and or,可以对Q对象进行& | ~操作
BookInfo.objects.filter(id__gt=3, bread__gt=30)
from django.db.models import Q
BookInfo.objects.filter(Q(id__gt=3)|Q(bread__gt=30))
BookInfo.objects.filter(~Q(id=3))
聚合函数:对查询结果进行聚合操作
sum count avg max min
aggregate:调用这个函数来使用聚合,返回值是一个字典
使用前需先导入聚合类:
from django.db.models import Sum,Count,Max,Min,Avg
BookInfo.objects.all().aggregate(Count('id')) # 不能用* 返回一个字典 {'id__count':5} key的命名方式
BookInfo.objects.all().aggregate(Sum('bread'))
count函数:返回值是一个数字 统计满足条件数据的数目,返回值是一个数字
BookInfo.objects.all().count()
BookInfo.objects.filter(id__gt==3).count()
对一个QuerySet实例对象,可以继续调用上面的所有函数
5、查询集
all,filter,exclude,order_by调用这些函数会产生一个查询集
QuerySet类对象可以继续调用上面的所有函数
查询集特性:
惰性查询:只有在实际使用查询集中的数据的时候才会发生对数据库的真正查询
缓存:当使用的是同一个查询集时,第一次的时候会发生实际数据库的查询,然后把结果缓存起来,之后再使用这个查询集时,使用的是缓存中的结果
限制查询集:
可以对一个查询集进行取下标或者切片操作来限制查询集的结果
对一个查询集进行切片操作会产生一个新的查询集,下标不允许为负数
取出查询集第一条数据的两种方式:b[0] b[0:1].get()
exists:判断一个查询集中是否有数据。 True False
books.exists()
6、模型类关系
1.一对多关系 models.ForeignKey()定义在多的类中
2.多对多关系 models.ManyToManyField()定义在哪个类中都可以
3.一对一关系 models.OneToOneField()定义在哪个类中都可以
7、关联查询(一对多)
在一对多关系中,一对应的类叫做一类,多对应的类叫做多类,把多类中定义的建立关联的类属性叫做关联属性
通过模型类实现关联查询
查询id为1的图书关联的英雄信息
b = BookInfo.objects.get(id=1)
b.heroinfo_set.all()
查询id为1的英雄关联的图书信息
h = HeroInfo.objects.get(id=1)
h.hbook
通过模型类实现关联查询
查询图书信息,要求图书关联的英雄的描述包含‘八’
BookInfo.objects.filter(heroinfo__hcomment__contains='八') -->转化为inner join语句
查询书名为aa的所有英雄
HeroInfo.objects.filter(hbook__btitle='aa')
通过模型类实现关联查询时,要查那个表中的数据,就需要通过哪个类来查
写关联查询条件的时候,如果类中没有关系属性,条件需要写对应类的名字,如果类中有关系属性,直接写关系属性
插入、更新和删除
调用一个模型类对象的save方法的时候就可以实现对模型类对应数据表的插入和更新
调用一个模型类对象的delete方法的时候就可以实现对模型类对应数据表数据的删除
8、自关联
自关联是一种特殊的一对多的关系
地区表:id,title,parentid
1 # models.py 2 class AreaInfo(models.Model): 3 '''地区模型类''' 4 # 地区名称 5 atitle = models.CharField(max_length=20) 6 # 关系属性,代表当前地区的父级地区 7 aParent = models.ForeignKey('self', null=True, blank=True)
显示广州市的上级地区和下级地区
1 # views.py 2 def areas(request): 3 '''获取广州市的上级地区和下级地区''' 4 # 1.获取广州市的信息 5 area = AreaInfo.objects.get(atitle='广州市') 6 # 2.查询广州市的上级地区 7 parent = area.aParent 8 # 3.查询广州市的下级地区 9 children = area.areaInfo_set.all() 10 # 使用模板 11 return render(request, 'booktest/areas.html', {'area':area,'parent':parent,'children':children})
<body> <h1>当前地区</h1> {{ area.atitle }}<br/> <h1>父级地区</h1> {{ parent.atitle }}<br/> <h1>下级地址</h1> <ul> {% for child in children %} <li>{{ child.atitle }}</li> {% endfor %} </ul> </body>
9、管理器
objects是Django自动生成的管理器对象,通过这个管理器可以实现对数据的查询
objects是models.Manger类的一个对象。自定义管理器之后Django不再生成默认的objects管理器
1)自定义一个管理类,继承models.Manager类
2)在具体的模型类里定义一个自定义管理器类的对象
1 class BookInfoManaher(models.Manager): 2 '''图书模型管理类''' 3 # 1.应用场景一:改变查询结果集 4 def all(self): 5 # 1.调用父类的all,获取所有数据 6 super().all() #QuerySet 7 # 2.对数据进行过滤 8 books = books.filter(isDelete=False) 9 # 3.返回books 10 return books 11 #2.应用场景二:管理器中定义一个方法操作模型类对应的数据表 12 # 封装函数:操作模型类对应的数据表(增删改查) 使用self.model()就可以创建一个跟自定义管理器对应的模型类对象 13 14 def create_book(self, btitle, bpub_date): 15 #1. 创建一个图书对象
#获取self所在的模型类
model_class = self.model
book = model_class() 16 book = BookInfo() 17 book.btitle = btitle 18 book.bpub_date = bpub_date 19 #2.保存进数据库 20 book.save() 21 #3.返回book 22 return book 23 24 25 class BookInfo(models.Model): 26 # ...... 27 objects = BookInfoManager()
模型管理器类和模型类关系
元选项
Django默认生成的表名:应用名小写_模型类名小写
元选项:需要在模型类中定义一个元类Meta,在里面定义一个类属性db_table就可以指定表名
1 class BookInfo(models.Model): 2 class Meta: 3 db_table = 'bookinfo'
模型类的表名不再依赖于应用的名字