Django简介
- 开放源码的web框架,基于python开发
- 核心思想:解耦
- 官网
MVC
- M:model 模型
- V:view 视图
- C:control 控制器
MTV
- M:model 模型
- T:template 模板
- V:view 视图
Django还有一个url分发器,处理URL请求
流程图解
图
环境部署
- conda create -n mylearn python=3.6
- activate mylearn
- conda install django=1.11
创建项目
- cd F:\Learn\python3\WEB\Django\mylearn
- django-admin startproject mylearn
- 目录结构
- mylearn/
- mylearn/
- init.py 定义mylearn包
- settings.py 项目配置文件
- urls.py URL配置
- wsgi.py 与WSGI兼容的WEB服务器入口配置
- manage.py django项目操作
- mylearn/
设计表结构
- 班级表grades
- 班级名称gname
- 成立时间gdate
- 女生总数ggirlnum
- 男生总数gboynum
- 是否删除isDelete
- 学生表students
- 姓名sname
- 性别sgender
- 年龄sage
- 简介scontend
- 所属班级sgrade
- 是否删除isDelete
配置数据库
- django默认使用sqlite
- settings文件DATABASES配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'djangodb',
'USER':'root',
'PASSWORD':'123456',
'HOST':'127.0.0.1'
}
}
- 安装PyMysql
- conda install pymysql
- 配置__init.py
import pymysql
pymysql.install_as_MySQLdb()
创建应用app
- 一个项目可以创建多个应用app
- cd F:\Learn\python3\WEB\Django\mylearn
- python manage.py startapp myApp
- myApp目录结构
- myApp/
- admin.py 站点配置
- models.py 模型
- views.py 视图
- myApp/
注册应用app
- settings文件INSTALLED_APPS配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myApp'
]
定义数据模型
- 一个模型对应一个表
- 一个模型也就是一个类,可以实例化
- 不需要定义表的主键,django会自动创建
在数据库中生成数据表
- 生成迁移文件
python manage.py makemigrations [appname]
- 在migrations目录生成迁移文件
- 执行迁移
python manage.py migrate [appname]
测试数据操作
- python manage.py shell
- 引入包
from myApp.models import Grades,students
from django.utils import timezone
from datetime import *
- 查询所有数据
Grades.objects.all()
- 添加数据
- 实例化对象
grade1 = Grades()
grade1.gname = "python04"
grade1.gdate = datetime(year=2018, month=5, day=3)
grade1.ggirlnum = 3
grade1.gboynum = 70
grade1.save()
- 查看某个对象
- g = Grades.objects.get(id=2)
- 修改数据
- grade2.gboynum = 60
- grade2.save()
- 删除数据
- 物理删除
grade2.delete()
- 关联对象
grade1 = Grades()
stu = Students()
stu.sname = "Leo"
stu.sgender = True
stu.sage = 28
stu.scontend = "I'm Leo"
stu.sgrade = grade1
stu.save()
- 获得关联对象的集合
grade1.students_set.all() 获取python04班级的所有学生
- 新增记录,直接新增到数据库中
stu3 = grade1.students_set.create(sname="Jack", sgender=True, scontend="I'm Jack", sage=30)
启动测试服务器
- python manage.py runserver [ip]:[port] 默认127.0.0.1:8000
- 基于python开发的轻量级web服务器,用于测试
admin站点管理
- 内容发布、增删改
- app应用管理
- 创建管理员用户
- python manage.py createsuperuser
- 汉化管理后台
- settings
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
- 管理数据表
- 修改myApp/admin.py
admin.site.register(Grades)
admin.site.register(Students)
- 自定义管理页面
- 列表页属性
- list_display 显示字段
- list_filter 过滤器
- search_fields 搜索字段
- list_per_page 分页
- 添加修改页属性
- fields 属性的先后顺序
- fieldsets 给属性分组,与fields不能同时使用
- 列表页属性
- 关联对象:在添加一个班级时直接新增学生
- 布尔值显示问题
def gender(self):
if self.sgender:
return "男"
else:
return "女"
gender.short_description = "性别"
- 执行动作位置
actions_on_bottom = True
actions_on_top = False
使用装饰器注册
视图的基本使用
- 在django中,视图对web请求进行回应
- 视图就是一个python函数,在views.py中定义
- 定义视图
def index(request):
return HttpResponse("Good Good study, Day Day up!")
def detail(request, num1, num2):
return HttpResponse("detail-{0}-{1}".format(num1, num2))
- 配置URL
#mylearn项目urls
urlpatterns = [
url(r'^', include('myApp.urls')),
url(r'^admin/', admin.site.urls),
]
#myApp目录下新建urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index),
url(r'^(\d+)/(\d+)/$', views.detail),
]
模板的基本使用
- 模板是html页面
- 根据视图传递的数据进行页面填充
- 创建模板目录
- 在项目目录下创建templates目录,然后创建对应app的模板目录myApp
- 配置模板路径
#项目settings
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
- 定义grades.html和students.html模板
- 模板语法
- {{ 变量|对象.属性 }}
- {% 执行代码段 %}
- 需求:http://127.0.0.1:8000/grades
模型详解
- django对各种数据库都提供了很好的支持
- django对各种数据库提供统一API调用
- 根据不同的业务需求选择不同的数据库
模型开发流程
- 配置数据库
- 定义模型
- 一个模型对应一个数据库表
- 生成迁移文件
- 执行迁移生成数据表
- 使用模型类进行数据的增删改查
ORM
- ORM 对象-关系-映射
- ORM图解
- 根据对象的类型生成表结构
- 将对象、列表的操作转换为sql语句
- 将sql查询到的数据转换为对象、列表
- ORM优势
- 减轻开发人员自己编写sql的负担
- 使应用对底层数据库透明,不需要因数据库变更而修改代码
定义模型
- 模型、属性、表、字段之间的关系
- 一个模型类在数据库中对应一张表
- 在模型类中定义的属性,对应该模型对应表中的一个字段
定义属性
- django根据属性的类型确定一下信息
- 当前选择的数据库支持字段的类型
- 渲染管理表单时使用的默认html控件
- 在管理站点最低限度的验证
- django会为表增加自动增长的主键,每个模型只能有一个主键,自定义主键后,django就不会自动生成默认主键
- 属性命名规则
- 遵循python变量命令规则
- 由于django的查询方式,不允许使用连续的下划线
- 库
- 定义属性时,需要指定字段类型
- 字段类型定义在django.db.models.fields目录下,使用from django.db import models
- 通过models.Field创建字段类型的对象,赋值给属性
- 逻辑删除
- 对于重要的数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认为False
- 字段类型
AutoField(不常用)
CharField(max_length=字符长度)
- 字符串,默认表单样式TextInput
TextField
- 大文本字段,超过4000字节时使用,默认表单样式Textarea
IntegerField
- 整型
DecimalField(max_digits=None, decimal_places=None)
- 浮点型 python的Decimal实例
- max_digits位数总数,decimal_places小数点后数字位数
FloatField
- 浮点型 python的Float实例
BooleanField
- 布尔值 True\False
NullBooleanField
- 布尔值 null\True\False
DateField(auto_now=False, auto_now_add=False)
- python的datetime.date实例
- auto_now保存对象时自动设置字段为当前时间,常用于最后一次修改
- auto_now_add 对象第一次创建时自动设置当前时间
- 对应表单控件TextInput
- auto_now auto_now_add default这些选项是互斥的,不能同时使用
TimeField
- python的datetime.time实例
DatetimeField
- python的datetime实例
FileField
- 文件上传字段
ImageField
- 继承FileField的所有属性和方法,但是对上传的对象校验,确认为image
- 图片上传字段
- 字段选项
- 通过字段选项实现对字段的约束
- null
- blank
- db_column 字段名称
- db_index 字段索引
- default 默认值
- primary_key 主键
- unique 是否唯一
- 关系
- foreignKey 一对多
- ManyToManyField 多对多
- OneToOneField 一对一
- grade.students_set
- grade.students
- student.sgrade_id
创建模型类
元信息
- 在模型类中定义Meta类
class Meta():
db_table="" #定义数据表名,不指定时默认为appname_classname
ordering=[id] #对象的默认排序字段,获取对象的列表时使用,升序
ordering=[-id] #同上,降序,排序会增加数据库开销
模型成员
- 类属性
- objects Manager类型对象,用于数据库交互
- 当没有自定义管理器时,django创建默认的管理器objects
- 自定义管理器
stu_obj = models.Manager()
- 自定义模型管理器后,django创建的默认管理器objects将会不存在
- 自定义管理器Manager类
- 模型管理器时Django的模型与数据库进行交互的接口,一个模型可以有多个模型管理器
- 作用:向管理器类中添加额外的方法
- 作用:修改管理器返回的原始查询结果集合
- 重写get_queryset()方法
class StudentsManager(models.Manager):
def get_queryset(self):
return super(StudentsManager,self).get_queryset().filter(isDelete=False)
- 重写get_queryset()方法
- 创建对象
- 目的:向数据库中添加数据
- 当创建对象时,django不会对数据库进行操作,只有调用对象save()方法时,才会对数据库进行操作
- init方法已经在models.Model中使用,在自定义的模型中无法使用
- 创建对象的方法
- 在模型定义中增加类方法
- 在定义管理器中添加一个方法
模型查询
- 查询集:从数据库中获取的对象集合
- 查询集可以有多个过滤器
- 过滤器就是一个函数,基于所给的参数过滤查询结果
- 从sql角度看,查询集合即select *语句,过滤器即加上where条件
查询集
- 在管理器上调用过滤器方法返回查询集
- 查询集经过过滤器后返回新的查询集,所以过滤器可以链式调用
- 惰性调用:创建查询集不会带来任何数据的访问,直到调用数据时,才会访问数据
- 直接访问数据库的情况:
- 迭代
- 序列化
- 与if合用
- 返回查询集的方法称为过滤器
- all() 返回查询集中所有数据
- filter() 返回符合条件的数据
- filter(key1=value1)
- filter(key1=value1, key2=value2,…)
- filter(key1=value1).filter(key2=value2)
- exclude() 排除符合条件的数据
- order_by() 排序
- values() 返回由字典组成的列表
- 返回单条数据
- get()
- 返回一个满足条件的对象,如果没有找到符合条件的对象,会抛出DoesNotExist异常
- 如果找到多个对象,抛出MultipleObjectsReturned异常
- count() 返回查询集中对象的个数
- first() 返回查询集中的第一个对象
- last() 返回查询集中的最后一个对象
- exists() 判断查询集中是否有数据,有返回true,没有返回false
- get()
- 限制查询集
- 查询集返回列表,可以使用下标方法进行限制,等同于sql中的limit,下标不能是负数
- 查询集的缓存
- 每个查询集都包含一个缓存,实现最小化访问数据库
- 在新建的查询集中,缓存初次为空,第一次对查询集取值,django会将查询出的数据做缓存并返回查询结果
下次查询时,直接使用查询集的缓存,不直接操作数据库 - 缓存存放在内存中,读取速度快
字段查询
- 实现sql中的where语句,做为方法filter()、exclude()、get()的参数
- 语法:属性__比较运算符=值
- 外键:属性_id
- 转义:like语句中使用%匹配站位,匹配数据中的%使用like ‘\%’
- filter(sname_contains=’%’)
比较运算符
- exact 判断,大小写敏感
- containt 是否包含,大小写敏感
- startswith 以value开头,大小写敏感
- endswith 以value结尾,大小写敏感
- iexact 同上,不区分大小写
- icontaint 同上,不区分大小写
- istartwith 同上,不区分大小写
- iendwith 同上,不区分大小写
- isnull 判断是否为空
- isnotnull 判断是否不为空
- in 是否包含在范围内
- gt 大于
- gte 大于等于
- lt 小于
- lte 小于等于
- year
- month
- day
- week_day
- hour
- minute
- second
跨关联查询:处理join查询,模型类名属性名比较运算符
- 查询快捷,pk,代表主键
- 聚合函数
- aggregate()函数,返回聚合函数的值
- Avg
- Count
- Max
- Min
- Sum
from django.db.models import Max,Min
maxAge = Students.objects.aggregate(Max('sage'))
- F对象
- 可以使用模型的A属性与B属性进行比较
from django.db.models import F
- F对象支持算术运算
- 可以使用模型的A属性与B属性进行比较
- Q对象
- 过滤器的方法中的关键字参数,条件为And模式
- ~Q 取反
视图
- 视图接受并响应web请求
- 视图的本质就是python中的函数
- 响应的内容
- 网页
- 重定向
- 错误视图
- 404 not found
- 500 server error
- json数据
- 网页
- 过程
URL配置
- 指定根级URL配置文件,settings.py文件中ROOT_URLCONF参数,默认已设置好
- urlpatterns
- URL实例列表
- URL对象,正则表达式,视图名称,别名
- URL正则匹配注意点:
- 通过RUL传参,在正则表达式中使用()
- 正则表达式最前面不需要加反斜杠/
- 正则表达式前加r,表示字符串不转义
- 引入其他URL配置
- 在对应的应用APP目录下创建urls.py,对应本应用的URL配置,使用include()方法
- URL的反向解析
- 在视图、模板中使用硬编码链接时,在URL配置发生变更时,动态生成新的链接地址
- 定义URL链接时使用name别名,模板中调用别名
视图函数
- 定义视图
- 本质是一个函数,返回页面
- 视图参数
- request,一个HttpRequest对象
- 通过URL正则表达式获取参数
- 视图一般存放位置views.py文件
- 错误视图
- 404 网页找不到,URL匹配不成功
- 在templates目录下定义404.html
- 配置settings.py
DEBUG = True #显示调试信息,不会使用404页面
ALLOWED_HOSTS = []
- 500 在视图代码中出现错误(服务器端)
- 400 错误出现在客户端的操作
- 404 网页找不到,URL匹配不成功
- HttpRequest对象
- 服务器接受http请求,会根据http报文创建HttpRequest对象
- views.py中视图函数的参数request就是HttpRequest对象
- Django创建好HttpRequest对象,在视图函数被调用时,传递HttpRequest对象
- HttpRequest对象属性
- path 请求的完整路径(不包括域名和端口)
- method 请求方式GET\POST等
- encoding 编码方式
- GET 类似字典的对象,包含GET请求的所有参数
- POST 类似字典的对象,包含POST请求的所有参数
- FILES 类似字典的对象,包含所有上传的文件
- COOKIES 字典,包含所有的cookie
- session 类似字典的对象,表示当前会话
- HttpRequest对象方法
- is_ajax() 如果是通过XMLHttpRequest发起的请求,返回True
- QueryDict对象 request对象中的GET、POST都属于QueryDict对象
- get() 根据键获取一个值
- getlist() 键的值以列表形式返回
- GET属性
- POST属性
- HttpRespone对象
- 作用:给浏览器返回数据
- HttpRequest对象由Django创建,HttpResponse对象由程序代码创建
- 用法
- 不调用模板直接返回
- 调用模板返回
- 使用render()方法
render(request, templateName[ context])
- 结合数据和模板,返回HTML页面
- 使用render()方法
- 属性
- content 返回的数据
- charset 返回数据的编码格式
- status_code 响应状态码,200,304,404
- content-type 指定输出的MIME类型
- 方法
- init 使用页面的内容实例化HttpResponse对象
- write(content) 以文件的形式写入
- flush() 以文件的形式输出缓冲区
- set_cookie(key, value, max_age=None, exprise=None)设置cookie
- delete_cookie(key) 删除cookie ,指定的cookie不存在时,不做任何操作
- 子类HttpResponseRedirect()重定向、跳转
from django.http import HttpResponseRedirect
def redirect1(request):
return HttpResponseRedirect('/redirect2')
#简写
from django.shortcuts import redirect
def redirect2(request):
return redirect('/redirect2')
- 子类JsonResponse
- 返回json数据,一般用于异步操作,ajax请求等
会话状态保持
- 概述
- http协议为无状态协议,不记录请求
- 客户端与服务器的一次通信就是一次会话
- 实现状态保持,就需要在客户端或服务器存储会话数据
- 存储方式
- cookie 所有数据存储在客户端,不存储敏感数据
- session 所有数据存储在服务器,在客户端用cookie存储session-id
- 目的
- 在一段时间内跟踪请求者的状态,实现跨页面访问当前的请求者的数据
- 注意
- 不同的请求者之间不会共享session,与请求者一一对应
- 启用session,django默认启用
- settings.py文件 INSTALLED_APPS中’django.contrib.sessions’, MIDDLEWARE中’django.contrib.sessions.middleware.SessionMiddleware’
- 使用session
- 启用session后每个HttpRequest对象都有一个session属性,类似字典的对象
- get(key, default=None) 根据键获取session值
- clear() 清空所有的会话
- flush() 删除当前的会话,并删除会话的cookie
- 设置过期时间
- set_expiry(value),不设置默认2周后过期
- 整数,request.session.set_expiry(10)
- 设置为0,即关闭浏览器即失效
- 设置为None,永不过期
- 存储session的位置
- 数据库
- 缓存
- 数据库和缓存
- 使用redis缓存session
模板
定义模板
- 变量:视图传给模板的数据
- {{ var_name }}
- 如果使用的变量不存在,则模板中无返回
- 在模板中使用点语法
- 字典查询
- 对象属性或者对象方法
- 数字索引
- 在模板中使用对象方法
- 在模板中不能传递参数
- 标签
- 语法: {% tag %}
- 作用
1. 在输出中创建文本
2. 控制语句
- if
```
{% if 表达式1 %}
语句1
{% elif 表达式2 %}
语句2
{% else %}
语句3
{% endif %}
```
- for
```
{% for 变量 in 列表 %}
语句1
{% empty %}
语句2
{% endfor %}
```
- {{ forloop.counter }} 当前是第几次循环
- comment 注释多行
```
{% comment%}
注释行
{% endcomment%}
```
- ifequal/ifnotequal 判断是否相等或不等
```
{% isequal value1 value2 %}
语句1
{%%}
```
- include 加载模板并以标签内的参数渲染
```
{% include '模板目录' 参数1 参数2 %}
```
- url 反向解析 {% url 'namespace:name' p1 p2 %}
- csrf_token CSRF保护,跨站请求伪造保护 {% csrf_token %}
- block、extends 用于模板继承
- autoescape 用于HTML转义
- 过滤器
- 作用:在变量显示前修改
- 用法:{{ var|过滤器 }}
- lower
- upper
- 过滤器可以传递参数,参数使用引号括起来
- join {{ list|join:'#'}}
- default 如果变量不存在,或者值为false、空、Null、None,可以使用默认值{{ test|default:'没有'}}
- date 根据给定格式转换日期为字符串, {{ dateVal|date:'y-m-d' }}
- HTML转义 escape
- 加减乘除
```
{{ num|add:10 }} #加
{{ num|add:-10 }} #减
{% num|widthradtio num 1 5 %} #乘
{% num|widthradtio num 5 1 %} #除
```
- 注释
- 单行注释 {# #}
- 多行注释 {# #}
模板继承
- 作用
- 减少页面内容的重复定义,实现页面内容重用
- block标签
- 在父模板中预留区域,子模板填充
{% block 标签名 %}
{% endblock 标签名 %}
- 在父模板中预留区域,子模板填充
- extend标签
- 继承模板,写在模板的第一行
- {% extends ‘父模板名’ %}
HTML转义
- 默认情况下,模板接收到有含义的代码,当做普通字符串渲染
- 需要将接收到的代码当做HTML代码渲染
- {{ code|safe }}
- {{ code|escape }}
{% autoescape off %}
{{ code }}
{% endautoescape %}
CSRF跨站请求伪造
- 某些恶意网站包含链接、表单、按钮、js,利用登录用户在浏览器中认证,从而攻击服务
- 防止CSRF
- 在settings.py配置
MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware',]
- {% csrf_token %}
- 在settings.py配置
验证码
- 作用
- 用户注册、登录页面时使用,防止暴力请求,减轻服务器压力
- 防止CSRF的一种方式
Django高级扩展
静态文件
- css、js、图片、json文件、字体文件等
- 配置settings.py
中间件
- 概述
- 轻量级、底层的插件,可以介入django的请求和响应
- 本质:一个python类
- 方法
- init 不需要传参数,服务器响应第一个请求时自动调用,用于确定是否启用该中间件
- process_request(self.request)
- 在执行视图前被调用(分配URL匹配视图之前)
- process_view(self.request, view_func, **kwargs)
- process_template_response(self.request, response)
- process_response(self.request, response)
- process_exception(self.request, exception)