请求与响应
一、过程
当用户请求一个页面时,Django 把请求的数据包装成一个 HttpRequest 对象,然后 Django 加载对应的view 函数,把这个 HttpRequest 对象作为第一个参数传给 view 函数。任何 view 函数都应该返回一个 HttpResponse 对象。
- 客户端发送一个请求,并携带参数到达服务器端 Browser -> Server
- 服务器会接收请求,并通过request对象获取参数
- 服务器会进行逻辑处理(查询数据库,验证)
- 服务器返回响应回到客户端 Server -> Browser
二、HttpResponse请求对象
HttpRequest 对象表示来自客户端的一个单独的 HTTP 请求。HttpRequest 对象是 Django 自动创建的,且会传递给视图函数作为第一个参数。
作用:
接收由页面传过来的参数,页面的标签属性都可以接收,比如form表单的name和value等
request.GET返回由键值对组成的字典
注意form表单的method方法,如果是由POST方法,使用request.POST
request.method返回form表单的方法,是字符串
三、HttpResponse响应对象
Request 和 Response 对象起到了服务器与客户机之间的信息传递作用。Request 对象用于接收客户端浏览器提交的数据,而 Response 对象的功能则是将服务器端的数据发送到客户端浏览器。
对于 HttpRequest 对象来说,是由 Django 自动创建, 但是,HttpResponse 对象就必须我们自己创建。每个 View 方法必须返回一个 HttpResponse 对象。
四、view跳转
1、跳转的情景
一个view接到请求,处理完业务逻后,最后都需要给出响应。而响应内容的生成是不由view负责,Template(模板)是专业的响应内容生成者,此时需要view和Template之间做衔接和跳转
- 基本的跳转:从view跳转到template(render(request,‘html’))
# view.py
from django.http import render
def index(request):
return render(request,'index.html') #跳转到模板的HTML文件中,注意是系统自动寻找template下的文件
- 复杂的跳转:view与view之间的跳转,在跳转到template(redirect())
def delete_employee(request):
try:
with transaction.atomic():
id = request.GET.get('name')
d=Employee.objects.get(id=id).delete()
if d:
print('删除%s成功'%id)
except Exception as e:
print(e)
return HttpResponse('删除失败')
else:
return redirect("/emsapp/show") 冲#重定向到ems文件下emsapp的show视图函数,注意emsapp前面的/
跳转方式
转发:基本的跳转,也就是浏览器的URL不变
转发是view到template的跳转,也就是视图函数(views)和模板(templates)之间的跳转render(request,'html')
重定向:是从一个视图函数(views)到另一个视图函数的跳转,浏览器的URL发生改变
redirect("/emsapp/show")
转发与重定向的区别
1、转发用于view和template,而重定向用于view和view
2、转发浏览器地址栏的URL不改变,而重定向地址栏的URL改变
五、Cookie
1、简介
Cookie是一种数据存储技术,由服务器(view视图函数)生成,并保存在客户端(浏览器)的一种技术。
HTTP协议是无状态的协议。一旦数据交换完毕。客户端与服务器的连接就会关闭,再次交换数据就需要建立新的连接、
2、使用场合
1、保存登录信息
2、保存用户搜索的关键词
3、使用Cookie
方法
对象:
HttpResponse对象,render对象、redirect对象,本质上都是HttpResponse对象
设置cookie
set_cookie(key,value,max_age)
key:设置的键
value:键的值
max_age:存活时间,默认是一个会话周期,也就是浏览器关闭后失效
max_age=0 会删除cookie
max_age=1 默认cookie,一个会话周期
max_age=其余数 存活的时间(以毫秒计数)
例子:
from django.http import HttpResponse
def index(request):
ren=HttpResponse('你好啊')
ren.set_cookie('name','huo')
return ren
读取cookie
通过服务器时,当再次访问项目时,request会携带本项目的所有cookie到达服务器,通过request对象可以读取到cookie中存取的数据
def read_cookie(request):
print(request.COOKIE) #返回字典
print(request.COOKIE.get('name'))#huo
return HttpResponse('读取成功')
解决cookie的中文问题
正常情况下,cookie是不能存取中文的,如果存取中文,需要转义
存取cookie
name='霍'.encode('utf-8').decode('latin-1')
读取cookie
request.COOKIE.get('name').encode('latin-1').decode('utf-8') #霍
六、Session
1、简介
Cookie是将少量信息存储于客户端(本机浏览器),而Session是一种将会话状态保存在服务器的技术。
Session一般是指浏览器这个页面打开到关闭的这段时间,Session用作多个请求之间,共享数据。
应用
淘宝的登陆之后,可以添加购物车,查询订单等
2、使用Session
配置文件
当前项目的settings.py=>INSTALL_APPS
INSTALLED_APPS = [
...
'django.contrib.sessions',
...
]
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
...
]
在使用session钱,需要做生成移植记录表,用于存储session数据,存储在数据库中
注意首先得创建数据库
在terminal中
python manage.py makemigrations 生成移植文件
python manage.py migrate 生成移植记录表
生命周期
默认session存活两周,但一般更改为一个会话周期
在settings.py中加上
SESSION_EXPIRE_AT_BROWSER_CLOSE=True
注意单词不要打错,打错了会失效
存储Session
def indeX(request):
request.session['name']='huo' 同cookie,以字典的形式
return HttpSession('存取成功')
读取Session
def read_session(request):
print(request.session) 字典
print(request.session.get('name')) 'huo'
......
手动清除session
1、request.session.flush() #清除cookie中的sessionid,清除数据表中的记录
2、request.session.clear()
3、del request.session['name'] 删除单个,注意没有会报错
存取位置
数据库:INSTALLED_APPS 中的 django.contrib.sessions 会在执行移植文件时生成数据表(默认)
缓存:为Project设置缓存组件,则session可以存入缓存,提高执行效率(redis)
文件:存于服务器本地文件中(不建议)
cookie:存取客户端的cookie中(不建议,适合小项目)
实现原理
浏览器第一次请求session对象时,服务器会创建一个session并且生成一个sessionId,存储在数据库中,并将sessionid返回给浏览器,这个sessionId会被保存在浏览器的会话cookie中
在浏览器不关闭的情况下,之后的每次请求请求头都会携带这个sessionId到服务器。服务器接收到请求后就得到该请求的sessionID,服务器找到该id对应的session返还给请求者使用。
Cookie和Session的选择
需要在多个请求间多次共享使用的数据,保持状态,使用session,如在多个请求间持续保持一些数据
需要在一段时间后依然可以保持的小块数据,使用cookie,如“记住我”,保证一段时间后,可以自动登录
每个网站在一个浏览器中的cookie数据上限是4k,session没限制
cookie存在浏览器本地,隐私性不好。安全性较低
七、全局错误视图
http请求的状态码 200=成功 404=资源未找到 500=服务器错误 400=bad request...
可以为常见的错误定制错误页面
关闭调试模式,设置allowed_hosts
在templates下新建:404.html 500.html 400.html,在出现对应错误时,会自动跳转错误页面
八、基于view驶入的事务控制
对应数据库中的事务,有些操作,要么全部执行,要么全部不执行
方式一
在settings.py中的database配置中加入
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'jangodb',
'USER':'root',
'PASSWORD':'123456',
'HOST':'localhost',
'PORT':3306,
'ATOMIC_REQUESTS':True #事务
}
}
原理
当有请求发送时,Django会在调用视图方法之前开启一个事务。如果请求正确处理,Django就提交该事务。否则,Django会回滚该事务
BUG问题
基于这种方式的事务处理,不能处理异常
def test(request):
try:
Person(name="tx_name22", age=18).save()
Person(name="tx_name33", age=18).save()
a=10/0
except Exception:
print("error")
raise
return render(request,"error1.html")
return render(request,"success.html")
这种方式,加了try,捕获异常,所以如果报错,会被捕获,也就是事务相当于没有作用
第二种方式
原理
通过调用transaction.atomic()方法开区事务,
def testt(request):
try:
with transaction.atomic():#开始一个事务 环境,with结束时,如果没有异常,事务提交;否则回滚
Person(name="tx_name22", age=18).save()
Person(name="tx_name33", age=18).save()
a=10/0
return render(request,"success.html")
except:
print("error") #此时的异常已经回滚
return render(request,"error.html") #还可以为错误提供专用的视图页面
注意事项
事务本身并没有处理异常的功能,一旦发生异常,事务只会回滚该数据
九、反向解析
1、简介
在实际的Django项目中,当我们在设置URL,如果我们改变了URL,那么在配置文件中都需要修改以前设置的URl
2、反向解析
所以需要一种更简单的方法,为了解决这个问题,Django提供了一个很方便的方法
只需在URL中提供一个name参数,并赋值一个你自定义的、好记的、直观的字符串。
通过这个name参数,可以反向解析URL、反向URL匹配、反向URL查询或者简单的URL反查。
urlpatterns = [
path('index/',views.index,name='index'),
]
3、使用
在模板语言中(也就是html中):
<a href="{% url 'index' %}"><a>
在python代码
def index(request):
return redirect('index')
4、URL命名空间
当有多个app的时候,可能函数名字名字会冲突,为了解决这个问题,app有唯一的名字
app_name='app_name' # 定义app_name
urlpatterns = [
path('index/',views.index,name='index'),
]
使用
def index(request):
url = reverse('app_name:index') # 使用方式 app_name:url_name
print(url)
return render(request, 'index.html')
<a href="{% url 'app_name:index' %}">反向解析</a>