1、模型概述
-
**模型(Models):**用来构建和操作你的web应用中的数据,模型是你的数据的唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。
-
模板(Templates):模板层提供了设计友好的语法来展示信息给用户。使用模板方法可以动态地生成HTML。模板包含所需HTML 输出的静态部分,以及一些特殊的语法,描述如何将动态内容插入。
-
视图(views):用于封装负责处理用户请求及返回响应的逻辑。视图可以看作是前端与数据库的中间人,它会将前端想要的数据从数据库中读出来给前端。也会将用户要想保存的数据写到数据库。
2、ORM
2.1ORM概念
ORM(Object Relational Mapping),由于python是面向对象的编程语言,而数据库是采用关系作为基础,ORM的作用是为了让我们采用面向对象的思路设计数据库,使数据库设计更加简单。
2.2 优势
Django的ORM操作本质上会根据对接的数据库引擎,翻译成对应的sql语句;所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、sqlite....,如果数据库迁移,只需要更换Django的数据库引擎配置即可。
二、Model层开发过程
1、安装数据库驱动
pip install mysqlclient 注意三种方式
2、数据库配置
修改settings.py中的DATABASES配置项
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
'NAME': 'test', # 数据库名
'USER': 'root', # 用户名
'PASSWORD': '123456', # 密码
'HOST':'localhost', # 主机ip
'PORT':3306, # 端口号
}
}
3、创建App,安装App(挂载APP)
- Django规定,如果使用模型,必须创建一个app:
python manage.py startapp app_name
-
修改settings.py文件INSTALLED_APPS
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app_name', # 创建的app名 ]
4、定义Model类
Model类是与数据库进行交互的模块
from django.db import models class User(models.Model): # 一个Model类将对应数据库中的一个表 -- 基类 name = models.CharField(max_length=30) age = models.IntegerField() salary = models.DecimalField(max_digits=7,decimal_places=2) birthday = models.DateTimeField()
5、生成移植文件记录
python manage.py makemigrations
6、执行移植操作
python manage.py migrate 也就是在数据库中创建表
三、模型字段
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,不能为空
default 定义默认值
primary_key 设置是否为主键
unique 列是否唯一
db_index 是否在列上建立索引
blank 默认Flase,用于前端页面的form验证(了解)
注意上面的参数都是True或Fasle
db_column 自定义列名,默认和field同名
3、元数据Meta
模型的元数据,指的是“除了字段外的所有内容”,例如排序方式、数据库表名、人类可读的单数或者复数名等等。
db_table = 'xxx' 设置表名(修改django默认生成的表名)
unique_together = (('列名1','列名2'),(...)) 设置联合唯一约束
ordering = ['列名1'] 或 ['列名1','列名2'] 列前加负号(-)代表反序
class MyModel(models.Model):
salary = models.DecimalField(...)
.....
age = models.xxx
name = models.xxx
class Meta:
unique_together = (("salary", "salary2"),("age","age2","age3"))
db_table="my_user"
ordering=['-age','name'] #根据age降序排列,如果age相同,再按照name升序排列
四、增删改
可以在views.py中
增
from app_name.models import User
user = User(name='a',age=18,salary=20000,birthdayday='1985-7-12 10:10:08') #创建对象
user.save() # 向数据库插入一条数据
# 或者
# 创建对象并保存数据,一步完成
user= User.objects.create(name='a',age=18,salary=20000,birthdayday='1985-7-12 10:10:08')
删
user = User.objects.get(pk=3) / (id=3)
user.delete()
# User.objects.get(pk=3).delete()
# 只删除id=3的数据 函数链 等价 user = User.objects.get(pk=3) user.delete()
User.objects.all().delete() # 删除所有数据
改
user = User.objects.get(age=18)
user.name="new_name"
user.save() # 注意:修改后要save()
五、查询操作
每个Model类都有一个默认的manager实例,名为objects。对数据库中对象的检索, 是通过 model Manager 来构造一个 QuerySet 对象来实现。Manager是对QuerySet进行管理的类
- QuerySet 对象是一个model 类对应的实例集合,是一个可遍历的结构 。
- manger 对象是可理解为对QuerySet进行管理的一个类,可以通过manager的一些方法获取到QuerySet集合
查询方法(user.objects)
all() 返回QuerySet对象,查所有
filter(条件) 返回QuerySet对象,筛选数据
exclude(条件) 除了条件的
first() 返回首个
last() 返回尾个
exists() 数据库表是否为空
order_by('列名) 根据列名进行排序
注意以上方法都是QuerySet对象的方法,而user.objects返回的是Manage对象,Manage对象调用QuerySet方法,Manage可以看成是一个中间人
count() 返回个数(QuerySet的方法)
get(条件) 返回model 对象
条件查询
不支持比较运算符,替换成lt(小于)、gt(大于)、lte(小于等于)、gte(大于等于)
例:
查询年龄大于二十的
User.objects.filter(age__gt=20)
注意:
列名需要用双下划线的方式
模糊查询
contains、icontains 包含(相当于sql的like,i表示忽略大小写)
startswith、istartswith 以什么开始
endswith、iendswith 以什么结束
注意:
上面的也需要以双下滑线的方式调用,都是以等号的方式
范围查询
in 在某个集合内(SQL中的in)
range 在范围内(SQL中的 between and)
双下换线开始,等号
空值查询
User.objects.filter(age__isnull=True) # 判断年龄是否为空
日期查询(了解)
- year
- month 1-12
- day
- hour
- minute
- second
- week 一年的第几周 1-52 or 53
- week_day 周几 周日=1 周六=7
User.objects.filter(birthday__year="2018")
User.objects.filter(birthday__month="1") # 生日是1月 可选值1-12
User.objects.filter(birthday__week_day__gt=1) # 生日日期大于周日
查询值
values() 返回所有的值,以字典的形式,可指定列
only() 优先查询某些列
聚合函数 aggregate
- Max( )
- Min( )
- Avg( )
- Sum( )
- Count( )
分组查询 annotate
Models.objects.values('age').annotate(Max("salary"))
# 分组查询时,是将values中的列作为分组条件的列
F()和Q()函数
F()函数是对自己的列进行操作的时候
User.objects.filter(id__lt=F('age')) #id小于age
Q()函数是进行或 (|) 非(~)” 逻辑时,可以使用Q
User.objects.filter(Q(id__lt=3)|Q(age__gt=F("id")*10))
Raw-SQL
Django支持原生的SQL语句
users = User.objects.raw("select id,name from userlist where id=1")
users = User.objects.raw("select id,name from userlist where age=%s and name=%s",[18,'Mr_lee'])
# 注意不要在外部拼接sql字符串
sql_str = "select id,name from userlist where age=%d and name='%s'"%(18,'Mr_lee')
User.objects.raw(sql_str) # 会有sql注入风险
sql_str = "select id,name from userlist where age=%d and name='%s'"%(18,"' or '1'='1")