day5_请求与响应

请求与响应

一、过程

当用户请求一个页面时,Django 把请求的数据包装成一个 HttpRequest 对象,然后 Django 加载对应的view 函数,把这个 HttpRequest 对象作为第一个参数传给 view 函数。任何 view 函数都应该返回一个 HttpResponse 对象。 

day5_请求与响应

  • 客户端发送一个请求,并携带参数到达服务器端 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('读取成功')

day5_请求与响应

解决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>
上一篇:day5-循环练习和列表


下一篇:长乐国庆集训Day5