——–模型models——-
模型 – Django对各种数据库都提供了很好的支持
Django为这些数据库提供了统一的API(接口),可以根据不同的业务需求选择不同的数据库
-
配置数据库
在__init__.py文件中添加import pymysqlpymysql.install_as_MySQLdb()修改settings.py :DATABASES
-
开发流程
1.配置数据库2.定义模型类 一个模型类都在数据库中一个表3.生成迁移文件4.执行迁移文件,生成数据表5.使用模型类进行对数据库的增删改查(crud)操作
-
ORM
概述:对象(O),关系(R),映射(M)任务: 根据对象的数据类型生成表结构将对象的列表的操作转换为SQL语句将SQL语句查询到的结果转换为对象、列表优点:极大减轻了开发人员的工作量,而且面对一种操作因数据库的变 更而重写代码
-
定义模型
模型、属性、表、字段间的关系:一个模型类在数据库中对应一张表,在模型中定义的属性,对应该模型对照的一个字段
定义属性
概述:django根据属性的类型确定以下信息-当前选择的数据库支持字段的类型-渲染管理表单时使用默认的html控件-在站点管理最低限度的验证-jiango 会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会在生成默认的主键列-属性命名限制:遵循标识符规则,不能是Python的保留关键字、由于django的查询方式,不允许使用连续的下划线库:-定义属性时,需要字段类型,字段类型被定义在django.db.models.fields目录下为了方便使用,被导入到django.db.models中使用方式导入from django.db import models通过models.fields创建字段类型对象,赋值给属性逻辑删除-对于重要的数据都做逻辑删除,不做物理删除,实现方法时定义isDelete属性,类型为BooleanField,默认值为False字段类型AutoField():一个根据实际ID自动增长的IntegerField,通常不指定,如果不指定一个主键字段将自动添加到模型中CharField(max_lengh=字符串长度):字符串,默认的站点表单样式时TextinputTextField():大文本字段,一般超过4000使用,默认的站点表单控件时textarea(文本域)IntegerFeild():”整数“DecimalField(max_digits=None(位数总数),decimal_places(小数点后的位数)=None):使用python的Decimal示例表示的十进制“浮点数”FloatField():用python的float示例来表示浮点数BooleanField():True/False字段,此字段的默认站点表单控制时checkboxinputNullBooleanField:支持null,true,false三种值DateField([auto_now=False,auto_now_add=False]):使用python的datetime.date示例表示的日期auto_now=True:每次保存对象时,自动设置该字段为当前时间,用于”最后一次修改“的时间戳它总是使用当前日期,默认时falseauto_now_add=True:当对象第一次被创建时自动设置当前时间,用于创建的时间戳,,他总是使用当前日期,默认为false说明:该字段默认对应的表单控件是一个Textinput,在管理员站点添加了一个javascript写的日历控件,和一个today的快捷按钮,包含了一个额外的invalid_date错误消息键注意:auto_now_add,auto_now,and default 这些设置时相互排斥的,他们之间的任何组合将发生错误结果TimeField():使用python的datetime.time示例表示的时间,参数时DateFieldDateTimeField():使用python的datetime,datetime示例表示日期和时间,参数同DateFieldFileField() :一个上传的文件的字段ImageField() : 继承了FileDield的所有属性和方法,但是对上传的对象进行校验,确保它是一个有效的image字段选项:概述:通过字段选项,可以实现对字段的约束,在字段对象时通过关键参数指定null:如果为True,django 将空值一null存储到数据库中,默认是Falseblank:如果为True,则该字段允许为空,默认是false注意:null时数据库范畴中的概念,blank时表单验证范畴的db_column :字段的名称,如果未指定,则使用属性的名称db_index : 若值为true ,则在表中会为此字段创建索引default:默认值primary_key:若为true,则该字段会称为模型的主键字段unique:如果为true ,这个字段在表中必须有唯一值关系:分类:ForeignKey 一对多,将该字段定义在多的一端中ManyToManyField:多对多,将字段定义在两端中(最好不写)OneToOneFeild:一对一,将字段定义在任意一端中(基本不用)用一访问多:格式:对象.模型类小写_set示例:grade.student_set用一访问一:(基本不用)格式:对象.模型类小写示例:grade.student访问id:格式:对象.属性_id示例:student.sgrade_id
创建模型类
元选项 :
在模型类中定义Meta类,用于设置元信息db_table=\"\" :定义数据表名,推荐使用小写字母,如果不写,数据表名默认为项目名小写_类名小写ordering=[] :对象的默认排序字段,获取对象的列表时可以使用示例:ordering=[\'id\'] 升序 、 ordering=[\'-id\'] 降序注意:排序会增加数据库的开销(消耗资源)
模型成员
-类属性:objects:-自己创建的属性 和 系统隐藏属性:objects他是Manager类型的一个对象,作用时与数据库进行交互-当定义的模型类没有指定管理器,django为模型创建一个objects的管理器自定义管理器:当为模型指定模型管理器,django就不在为模型类生成objects模型管理器了stuObj = models.Manager() #stuObj就是自定义模型管理器,此时objects不存在了自定义模型管理器Manager()类模型管理器是django模型与数据库进行交互的接口,一个模型可以有多个模型管理器作用:1.向管理器类中添加额外的方法2.修改管理器返回的\"原始查询集\"(没有任何过滤的数据库所有数据)重写get_queryset()方法------------------------------------------------------------------------------class StudentsManger(models.Manager):#自定义模型管理器(重写原始查询集)def get_queryset(self):return super(StudentsManger,self).get_queryset().filter(isDelete=False)class Students(models.Model):#构建自定义管理器,使用修改后的查询集stuObj = StudentsManger()------------------------------------------------------------------------------创建对象:目的:向数据库中添加数据当创建对象时,django不会对数据库进行读写操作,当调用save()时候才与数据库进行交互,将对象保存到数据库表中注意:__init__方法已经在父类models.Model中使用,在自定义的模型中无法使用方法:-1、在模型类中增加一个类方法----------------------------------------------------------------------------models.py:@classmethoddef createStudent(cls,name,age,gender,contend,grade,lastT,createT,isD=False):#创建对象stu = cls(sname=name,sage=age,sgender=gender,scontend=contend,lastTime=lastT,createTiem=createT,isDelete=isD,sgrade=grade)#返回对象return stuviews.py:def addstudent(request):grade = Grades.objects.get(pk=1)#向models.py中的addStudent()传递参数stu = Students.createStudent(\"刘德华\",34,True,\"我是刘德华\",grade,\"2020-4-10\",\"2020-4-15\")stu.save()return HttpResponse(\"dsad\")-2、在自定义管理器中添加方法-------------------------------------------------------------models.py:class StudentsManger(models.Manager):#自定义模型管理器(重写原始查询集)def get_queryset(self):return super().get_queryset().filter(isDelete=False)#创建对象第二种方式:def creatStudent(self,name,age,gender,contend,grade,lastT,createT,isD=False):stu = self.model()# print(type(grade))stu.sname=namestu.sage=agestu.sgender=genderstu.scontend=contendstu.sgrade=gradestu.lastTime=lastTstu.createTiem=createTreturn stuviews.py:def addstudent2(request):grade = Grades.objects.get(pk=1)stu = Students.stuObj.creatStudent(\"张学友\",31,True,\"我是张学友\",grade,\"2020-4-10\",\"2020-4-15\")stu.save()return HttpResponse(\"bbb\")模型查询:概述:1.查询表示从数据库获取的对象的集合(原始查询集)2.查询集可以有多个过滤器3.过滤器就是一个函数,基于所给的参数限制查询集结果4.从sql角度说:查询集和select语句等价,而过滤器就想where条件语句查询集:概念:1.在管理器上调用过滤器方法返回查询集2.查询集经过过滤器筛选后返回新的查询集,所以说可以写成链式调用3.惰性执行:创建查询集不会带来任何的数据访问,直到调用数据时,才会访问数据4.直接访问数据的情况:1,迭代 2.序列化 3.与if合用5.返回查询集的方法称为”过滤器“-all()返回查询集中的所有数据-filter(key=value) 保留符合条件的数据filter(key=value,key=value) 两个条件时\"且\"的关系即andfilter(key=value).filter(key=value) 链式-exclude() 过滤掉符合条件的数据-order_by() 排序-values() 一条数据就是一个一个对象(字典),返回一个列表[{....},{}]6.返回单条数据:get() 返回一个满足条件的对象注意:1.如果没有找到符合条件的对象,会引发\"模型类.DoesNotExists\"异常2.如果找到多条对象,也会引发\"模型类.MultipleObjectsReturned\"异常count() 返回当前查询集中的对象个数first() 返回当前查询集中的第一个对象last()返回当前查询集中的最后一个对象exists() 判读查询集中是否有数据,有True,反之false7.限制查询集查询集返回列表,可以使用下标的方法进行限制(切片),等同于sql中的Limit语句注意:下标不能时负数8.查询集的缓存(高速缓存)概述:每个查询集都包含一个缓存,来最小化的对数据库的访问在新建的查询集中缓存,首次为空,第一次对查询集求值,会发生数据缓存,django会将查询出来的数据进行缓存,并返回查询结果,以后的查询直接使用查询集合的缓存9.字段查询概述:实现了Sql 中的where语句,作为fiter(),exclude(), get()的参数语法:属性名称__比较运算符=值 注意:两个下划线外键:属性名_id转义:sql中like语句中使用%时为了匹配展位,匹配数据中的%(where like \'%\')比较运算符:1.判断,区分大小写filter(isDelete=Flase)2.contains 是否包含,区分大小写 像sql中的likestudentsList = Students.stuObj.filter(sname__contains=\"l\")3.startswith、endswith 以value开头或结尾,区分大小写studentsList = Students.stuObj.filter(sname__startswith=\"l\")注意:以上四个在前面加上i,就表示不区分大小写:icontains4.isnull , isnotnull 是否为空filter(sname__isnull=False)5.in 是否包含在范围内studentsList = Students.stuObj.filter(pk__in=[1,3,4])6.gt gte lt lte 大于 大于等于 小于 小于等于studentsList = Students.stuObj.filter(sage__gt=30)7.year month day week_day hour minute secondstudentsList = Students.stuObj.filter(createTiem__year=2020)8.跨关联查询处理类似sql中innner join ,语法:模型类名小写__属性名__比较运算符grade = Grades.objects.filter(students__scontend__contains=\"我是刘德华\")9.查询快捷pk 代表主键聚合函数使用aggregrate()函数返回聚合函数的值导入包:from django.db.models import Max,CountAvgCountMaxmaxAge=Students.stuObj.aggregate(Max(\'sage\'))MinSumF对象:(两个属性之间的比较)导入包:from django.db.models import F,Q可以使用模型A属性和B属性进行比较g=Grades.objects.filter(ggirlnum__gt=F(\'gboynum\'))#女生人数大于男生人数的班级支持F对象的算数运算g=Grades.objects.filter(ggirlnum__gt=F(\'gboynum\')+20)Q对象:(解决属性间\"或\",\"非\")概述:过滤器的方法中的关键字参数,条件为And模式or查询:stu=Students.stuObj.filter(Q(pk__lt=3)|Q(sage__gt=30))取反:stu=Students.stuObj.filter(~Q(pk__lt=3))