ORM:(object-relational-mapping)
1、根据对象的类型生成表结构
2、将对象、列表的操作转换为sql语句
3、将SQL语句查询到的结果转换为对象、列表
优点:减轻工作量,不需因数据库改变而修改代码
一、定义模型:
1、一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表中的一个字段
2、 定义属性:
3、创建模型类
4、元选项:在模型类中定义一个Mate类,设置元信息。
db_tables : 定义数据表名(小写), 默认为 项目名_类名小写
ordering : 对象的默认排序字段,获取对象的列表时使用(会增加数据库开销)
ordering [ ' id'] : 升序
ordering [ ' -id'] : 降序
二、模型成员
1、类属性
objects : 是Manager类型的一个对象,与数据库进行交互。当定义模型类没有指定管理器,则Django为模型创建一个名为objects的管理器。
自定义管理器:指定管理器之后,objects就不存在了
自定义管理器类:模型管理器是Django的模型与数据库进行交互的接口,一个模型可有多个模型管理器。
作用: 向管理器类中添加额外的方法。修改管理器返回的原始查询集合。(重写get_queryset())
eg.列出所有学生
(1)自定义管理器前
from SC.models import Grades, Students
from django.utils import timezone
from datetime import *
Students.objects.all()
(2)自定义管理器
# SC/models.py
class StudentsManager(models.Manager): # 自定义管理器类
def get_queryset(self):
return super(StudentsManager, self).get_queryset().filter(isDelete=False) # 过滤
class Students(models.Model):
stuObj = models.Manager() # 自定义管理器------> 原始查询集
stuObj2 = StudentsManager() # 过滤后的查询集
>>>Students.objects.all()
AttributeError: type object 'Students' has no attribute 'objects'
>>>Students.stuObj.all()
Out[5]: , , , ]>
>>>Students.stuObj2.all() # 若把shit的 isDelete修改为 1 , 则 查询结果不会显示shit
2、创建对象 ( 向数据库中添加数据)
当创建对象时, Django不会对数据库进行读写操作,当调用save()时才与数据库交互,将对象保存在数据库表中。
__init__方法已经在父类models.Model中使用,在自定义模型中无法使用。
方法: 1. 在模型类中添加一个方法
# SC\views.py
def addstudent(request):
grade = Grades.objects.get(pk=1)
stu = Students.createStudent("jake", 11, True, "dddddddddd", grade)
stu.save()
return HttpResponse("aaaaaaaaaaaaaaaaaaaaaaa")
# SC\urls.py
url(r'^addstudent/$', views.addstudent),
# SC\models.py
class Students(models.Model):
# 定义一个类方法创建创建对象
@classmethod
def createStudent(cls, name, age, gender, content, grade, isD=False):
stu = cls(sname = name, sage = age, sgender = gender, scontent = content, sgrade = grade, isDelete =isD
)
return stu
2. 在定义管理器中添加一个方法。
# SC\urls.py
url(r'^addstudent/$', views.addstudent),
# SC\views.py
def addstudent2(request):
grade = Grades.objects.get(pk=1)
stu = Students.stuObj2.createStudent("jake", 11, True, "dddddddddd", grade)
stu.save()
return HttpResponse("aaaaaaaaaaaaaaaaaaaaaaa")
# SC\models.py
class StudentsManager(models.Manager):
def get_queryset(self):
return super(StudentsManager, self).get_queryset().filter(isDelete=False)
def createStudent(self, name, age, gender, content, grade, isDelete = False):
# grade = Students()
stu = self.model() # 创建对象
stu.sname = name
stu.sage = age
stu.sgender = gender
stu.scontent = content
stu.sgrade = grade
return stu
三、模型查询
1、概述
查询集: 从数据库中获取的对象集合
查询集可以有多个过滤器
过滤器就是一个函数,基于所给的参数,限制查询结果。
从SQL角度来说, 查询集合与select 语句等价,过滤器就像where 条件
2、查询集:
在管理器上调用过滤器方法返回查询集
查询集经过过滤器筛选后返回新的查询集,所以可写成链式调用
惰性执行, 创建查询集不会带来任何数据的访问, 知道调用数据时,才会访问数据。
直接访问数据的情况 : 迭代, 序列化, 与if 合用
返回查询集的方法 称为 过滤器 : all(); filter(key=value, key=value) 或 filter(key=value).filter(key=value) ; exclude() 过滤掉符合条件的数据。 ; order_by() 排序。 ; values()一条数据就是一个对象(字典), 返回一个列表
返回单个数据: get()---返回一个满足条件的对象; first() ; last() ; exists() : 判断查询集中是否有数据,返回True/ False.
限制查询集: 查询集返回列表可用下标进行限制 ( 下标不能是负数)
# SC/views.py 显示前五条记录
def students2(request):
# studentsList = Students.objects.all()
studentsList = Students.stuObj2.all()[0:5] # 下标
return render(request, 'SC/students.html', {"students": studentsList})
# SC/urls.py
url(r'^students2/$', views.students2),
# views.py 分页显示学生
def stupage(request, page):
page = int(page)
studentsList = Students.stuObj2.all()[(page - 1) * 5: page * 5]
return render(request, 'SC/students.html', {"students": studentsList})
url(r'^stu/(\d+)/$', views.stupage),
查询集的缓存: 每个查询集都包含一个缓存,来最小化地对数据库进行访问。在新建的查询集中,缓存首次为空,第一超对查询集求值,会发生数据缓存,Django会将查询出来的数据做一个缓存。
字段查询: 实现了SQL中的where语句,作为方法filter() / exclude()/ get() 的参数。
exact/contains/startswith/endswith (若在此四个关键字前面加 i , 表示不区分大小写)
isnull/isnotnull/in
gt/gte/it/ite > / >= / < / <=
year / month / day / week_day / minute / second
跨关联查询: 模型类名__属性名__比较运算符
# 查询名字中含有某个关键字的记录
def studentsearch(request):
studentsList = Students.stuObj2.filter(sname__contains="k")
return render(request, 'SC/students.html', {"students": studentsList})
url(r'^studentsearch/$', views.studentsearch),
# 查询名字以f开头的记录
def studentsearch(request):
studentsList = Students.stuObj2.filter(sname__startswith="k")
# 取ID是2 4 6 8 的记录
def studentsearch(request):
studentsList = Students.stuObj2.filter(pk_in=[2,4,6,8])
# 取最后修改日期为2017的记录
def studentsearch(request):
studentsList = Students.stuObj2.filter(lastTime__year=2017])
grade = Grades.objects.filter(students__scontent__contains='xxx') # 描述中带有‘xxx’这个字符的数据属于哪个班级
聚合函数:
aggregate() 返回聚合函数的值. 参数: Max / Min / Sum / Avg /Count
from django.db.models import Max
maxAge = Students.stuObj2.aggregate(Max('sage')) # 年龄最大的记录
print(maxAge)
F对象 : 使用模型的A属性 与 B属性比较 , 还支持对象的算术运算
Q对象: 过滤器的方法中的关键字参数,条件为And模式, 进行or查询。若只有一个Q对象,则只用于匹配。 ~Q 取反。
# 输出女生人数大于男生的班级
from django.db.models import F,Q
g = Grades.objects.filter(girl_num__gt=F('boy_num'))
print(g)
# 班级ID<3 或 年龄> 50的 : studentsList = Students.stuObj2.filter(Q(pk__lte==3) | Q(sage__gt=50))