模型_01
一、模型简介
1、模型概述
模型(Models):用来构建和操作你的web应用中的数据,模型是你的数据的唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。
**模板(Templates)**:模板层提供了设计友好的语法来展示信息给用户。使用模板方法可以动态地生成HTML。模板包含所需HTML 输出的静态部分,以及一些特殊的语法,描述如何将动态内容插入。
视图(views):用于封装负责处理用户请求及返回响应的逻辑。视图可以看作是前端与数据库的中间人,它会将前端想要的数据从数据库中读出来给前端。也会将用户要想保存的数据写到数据库。
2、ORM
2.1 ORM概念
ORM是对象关系映射(Object Relational Mapping)的缩写,由于程序设计者更多采用面向对象的思想,而数据库则以关系作为其基础,ORM的作用使得我们可以采用面向对象的思路来设计数据库,使数据库设计更加简单。
1 | 写类和对象 -> 操作数据库 |
2.2 ORM的优势
Django的ORM操作本质上会根据对接的数据库引擎,翻译成对应的sql语句;所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、sqlite….,如果数据库迁移,只需要更换Django的数据库引擎配置即可。
二、Model层开发过程
1、安装数据库驱动
1 | pip install mysqlclient |
2、数据库配置
在项目的 settings.py 文件中找到 DATABASES 配置项,将其信息修改为:
1 | DATABASES = { |
3、创建App,安装App(挂载APP)
- Django规定,如果要使用模型,必须要创建一个app:
1 | python manage.py startapp testapp |
- 安装App 在settings.py文件中
1 | INSTALLED_APPS = [ |
4、定义Model类
在App目录下的Models.py文件中,添加Model类:
1 | from django.db import models |
5、生成移植文件记录
1 | python manage.py makemigrations # 生成迁移记录 |
补充:python manage.py sqlmigrate modelapp 0001
查看对应的sql语句
6、执行移植操作
1 | python manage.py migrate # 执行迁移操作--应用到数据库 |
7、测试Model
1 | -- views.py -- |
三、模型字段
1、常用字段类型
字段类型 | 说明 |
---|---|
AutoField | 一般不用直接使用,Model中默认的主键类型。 Django默认给每个Model一个主键字段(如果没有自己定义的话) |
SmallIntegerField | 2字节 smallint |
IntegerField | 4字节 int |
BigIntegerField | 8字节 bigint |
FloatField | double |
DecimalField | DecimalField(max_digits=5,decimal_places=2) decimal。 必填:max_digits=5 #共有几位数 必填:decimal_places=2#其中小数位占几位 |
CharField | CharField(max_length=20) max_length是必填属性 == varchar(20) |
TextField | longtext |
BooleanField | 接收“True/False” tinyint |
NullBooleanField | 接收“True/False/None” tinyint |
DateTimeField | datetime |
DateField | 可选:auto_now=true 可做修改时间记录 可选:auto_now_add=True 可做首次添加时间 注意:以上两属性之一指定后,该字段不允许被编辑 |
TimeField | time |
ForeignKey | ForeignKey(to=关系对方的类或类名或‘self’,on_delete=级联选项) |
OneToOneFiled | OneToOneFiled(to=关系对方的类或类名或‘self’,on_delete=级联选项) |
ManyToManyFiled | ManyToManyFiled(to=关系对方的类或类名或‘self’) |
2、字段参数
null 默认False,不能为空
1
name = models.CharField(max_length=20,null=True) #可为空
default 定义默认值
1
2
3name = models.CharField(max_length=20,default="Mr_lee9")
age = models.IntegerField(default=18)
birthday = models.DateTimeField(default="2018-12-12")默认值不会作用在数据库上,而是django自己的约定,通过Model.save()时,会使用默认值
primary_key
1
2id = models.AutoFiled(primary_key=True) #默认追加,不用自己定义
id = models.CharField(primary_key=True,max_length=32)#如果需要字符串类型的ID可以自己定义unique 列是否唯一
1
name = models.CharField(max_length=20,unique=True)
db_column 自定义列名,默认和field同名
1
name = models.CharField(max_length=20,db_column="name9")
db_index 是否在列上建立索引
1
name = models.CharField(max_length=20,db_index=True)
blank 默认Flase,用于前端页面的form验证(了解)
1
note = models.CharField(max_length=20,blank=True)
3、元数据Meta
模型的元数据,指的是“除了字段外的所有内容”,例如排序方式、数据库表名、人类可读的单数或者复数名等等。
- db_table = ‘xxx’ 设置表名(修改django默认生成的表名)
- unique_together = ((‘列名1’,’列名2’),(…)) 设置联合唯一约束
- ordering = [‘列名1’] 或 [‘列名1’,’列名2’]
1 | class MyModel(models.Model): |
四、Model-API增删改
1、创建对象(添加数据)
在Terminal中执行python manage.py shell
进入python解释器或直接点“Python Console”进入python环境:
1 | from testapp.models import User |
2、删除数据
1 | user = User.objects.get(pk=3) / (id=3) |
3、修改数据
1 | user = User.objects.get(age=18) |
五、查询操作
1、QuerySet
每个Model类都有一个默认的manager实例,名为objects。对数据库中对象的检索, 是通过 model Manager 来构造一个 QuerySet 对象来实现。
- QuerySet 对象是一个model 类对应的实例集合,是一个可遍历的结构 。
- manger 对象是可理解为对QuerySet进行管理的一个类,可以通过manager的一些方法获取到QuerySet集合
1 | User.objects # 返回的是manager对象 |
2、查询方法
如下所有查询方法都是QuerySet实现的,只不过每个Model中都会有一个Manager,Manager接受到如下方法的调用时,会去调用QuerySet的方法,最终实现数据查询。
所以QuerySet这个类是查询动作的核心支撑。
Manager的任务是管理QuerySet,即,在需要的时候去调用QuerySet的对应方法。
2.1 基本查询方法
- all() – 返回值是QuerySet对象,包含了查询到的所有的数据行对应的Model对象
1 | User.objects.all() #返回QuerySet,其中是所有User的数据 |
- get() – 返回一个model对象
1 | # id为1的数据 |
- filter() – 返回QuerySet对象
1 | #filter如果不穿参数 默认查所有 |
- count()
1 | User.objects.count() #数据数量 |
- exclude() -QuerySet (了解)
1 | User.objects.exclude(pk=1) #和filter相反,取不满足条件的数据,返回QuerySet |
- first() - 对象 (了解)
1 | User.objects.first() #获取QuerySet中的第一个元素,返回一个对象或None |
- last() - 对象 (了解)
1 | User.objects.last() #获取QuerySet中的最后一个元素,返回一个对象或None(空queryset调用返回None) |
- exists() - Boolean (了解)
1 | User.objects.exists() #User对应的表中是否有数据,判断数据表是否为空。返回True/False |
补充:将QuerySet对象转为list
1 | list(User.objects.all()) |
2.2 排序 order_by(‘列名’)
1 | User.objects.order_by("pk") #根据id升序,返回QuerySet |
2.3 限制操作
取结果集中的某一部分数据
1 | User.objects.filter(pk=1,name="Mr_lee")[2] #返回QuerySet中第3个对象 |
2.4 条件查询
在众多查询方法中适合做条件查询的有:get(pk=1)、filter(name=”xx”)、exclude(pk=1)
get(pk=1,name=”Mr_lee”) 如此只是等值查询,远不能满足查询需求。
对于比较运算:
并不支持【> < >= <=】这些符号的操作,替换为关键字lt、gt、lte、gte
1 | User.objects.filter(pk__lt=10) #id小于10 |
2.5 模糊查询
- contains、icontains 包含、包含(对大小写不敏感–忽略) “%xx%”
- startswith、istartswith 以..开始 “xx%”
- endswith、iendswith 以..结尾 “%xx”
1 | User.objects.filter(name__contains="s") #name中包含"s" |
2.6 范围查询
- in 在某个集合中 id__in=(1,2,4)
- range 在某个范围中 id__range=(2,5)
1 | User.objects.filter(name__in=("Mr_lee","zz")) # where name in("Mr_lee","zz") |
2.7 空值查询
1 | Employee.objects.filter(name=None) |
2.8 日期查询(了解)
year
month 1-12
day
hour
minute
second
week 一年的第几周 1-52 or 53
week_day 周几 周日=1 周六=7
1
2
3User.objects.filter(birthday__year="2018")
User.objects.filter(birthday__month="1") # 生日是1月 可选值1-12
User.objects.filter(birthday__week_day__gt=1) # 生日日期大于周日
2.9 映射查询-部分列
select * from t_user;
查询全部列
select id,name from t_user;
查询部分列–映射查询
- values() 返回QuerySet对象,包含的元素都是dict
1 | User.objects.values() # 返回QuerySet对象,包含的元素都是dict User.objects.values() |
2.10 聚合函数(需要导包) - aggregate
- Max( )
- Min( )
- Avg( )
- Sum( )
- Count( )
1 | from django.db.models import Count, Max,Avg,Min,Sum |
2.11 分组查询 - annotate\
语法:
1 | Models.objects.values('age').annotate(Max("salary")) |
示例:
1 | User.objects.values('age').annotate(Count('age')); |
1 | #每种年龄中的用户的最大id和用户的最小生日 |
2.12 F()和Q()函数
User.objects.filter(id__gt=1) #id大于1
问题:查询id大于age的用户? 尝试:User.objects.filter(id__gt=age)–错误
User.objects.filter(id__gt=”age”)–错误
- 当查询条件中需要另外的列时,可以使用F
User.objects.filter(id__gt=F(‘age’))–正确
1 | from django.db.models import F |
User.objects.filter(id__lt=2,name__contains=”a”) #id小于2 而且 name包含“a”
问题:查询id小于2 或 name含有“a”的数据?
查询name不含有“a”的数据?
- 当需要 “或 (|) 非(~)” 逻辑时,可以使用Q
1 | from django.db.models import Q |
六、Raw-SQL-懒加载
如果以上的支持不能满足需求,Django也支持直接执行原生SQL语句。
1 | users = User.objects.raw("select id,name from userlist where id=1") |