python--Django快速入门之视图层详解

python 专栏收录该内容
46 篇文章 0 订阅

视图层详解

Django框架中的视图(View)是用来负责处理用户请求和返回响应的逻辑程序
视图(View)简而言之就是一个Python的函数或方法,接受处理Web请求。
视图的响应可以是网页的HTML内容,重定向或404错误,XML文档或图像。
视图的代码按惯例是放置一个名为 views.py 的文件中,此文件放在项目或应用程序目录中。
(其实视图文件名可以自己定义)

一 HttpReqeust对象

服务器接收到http协议的请求后,会根据报文创建HttpRequest对象
视图函数的第一个参数是HttpRequest对象
在django.http模块中定义了HttpRequest对象的API

1 请求对象的属性

path:一个字符串,表示请求的页面的完整路径,不包含域名
method:一个字符串,表示请求使用的HTTP方法,常用值包括:‘GET’、‘POST’
encoding:一个字符串,表示提交的数据的编码方式
如果为None则表示使用浏览器的默认设置,一般为utf-8
这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何
访问将使用新的encoding值
GET:一个类似于字典的对象,包含get请求方式的所有参数
POST:一个类似于字典的对象,包含post请求方式的所有参数
FILES:一个类似于字典的对象,包含所有的上传文件
COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串
session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的
支持时才可用,详细内容见“状态保持”

2 请求对象的方法

is_ajax() :如果请求是通过XMLHttpRequest发起的,则返回True

二 HttpResponse对象

在django.http模块中定义了HttpResponse对象的API
HttpRequest对象由Django自动创建,HttpResponse对象由程序员创建
在每一个视图函数中必须返回一个HttpResponse对象,当然也可以是HttpResponse子对象

视图的响应可以是网页的HTML内容,重定向或404错误,XML文档或图像。

1 响应HTML内容

from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)

2 响应重定向

重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它位置

def current_datetime(request):
# redirect重定向
reverse反向解析url地址
return redirect(reverse('index'))

3 响应404错误

def current_datetime(request):
# 方法一: 直接返回一个404,没有去加载404的模板页面
# return HttpResponseNotFound('<h1>Page not found</h1>')
# 方法二: 可以直接返回一个status状态码
# return HttpResponse(status=403)
# 方法三: 返回一个404的错误页面
raise Http404("Poll does not exist")

4 响应Json数据

from django.http import JsonResponse
def current_datetime(request):
now = str(datetime.datetime.now())
return JsonResponse({'now': now})

三 Cookie缓存

Cookie 是由 Web 服务器保存在用户浏览器(客户端)上的小文本文件,它可以包含有关用户的信息。
服务器可以利用Cookies包含信息的任意性来筛选并经常性维护这些信息,以判断在HTTP传输中的状
态。
Cookies最典型的应用是判定注册用户是否已经登录网站

1 设置cookie

def set_cookie(request):
# 获取当前的 响应对象
response = HttpResponse('cookie的设置')
# 使用响应对象进行cookie的设置
response.set_cookie('a','abc')
# 返回响应对象
return response

2 获取cookie

# 读取
a = request.COOKIES.get('a',None)
if a:
return HttpResponse('cookie的读取:'+a)
else:
return HttpResponse('cookie不存在')

3 QueryDict对象

定义在django.http.QueryDict
request对象的属性GET、POST都是QueryDict类型的对象

# http://127.0.0.1/get?a=1&b=2&c=3
# 一键一值
request.GET['name']
request.GET.get('name',None)
request.POST['name']
request.POST.get('name',None)

与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况

# http://127.0.0.1/get?a=1&a=2&b=3
# 一键多值
request.GET.getlist('name',None)
request.POST.getlist('name',None)

四 FBV和CBV

1 FBV

FBV(function base views) 就是在视图里使用函数处理请求。

2 CBV

CBV(class base views) 就是在视图里使用类处理请求。Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封
装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主
要下面两种:

  1. 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
  2. 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

如果我们要写一个处理GET方法的view,用函数写的话是下面这样。

from django.http import HttpResponse
def my_view(request):
if request.method == 'GET':
return HttpResponse('OK')
如果用class-based view写的话,就是下面这样
from django.http import HttpResponse
from django.views import View
class MyView(View):
def get(self, request):
return HttpResponse('OK')

Django的url是将一个请求分配给可调用的函数的,而不是一个class。针对这个问题,class-basedview提供了一个 as_view() 静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用 dispatch() 方法, dispatch() 方法会根据request的method的不同调用相应的方法来处理request(如 get() , post() 等)。到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。
在url中,就这么写:

urlpatterns = [
url(r'^index/$', MyView.as_view()),
]

五 响应文件案例: 验证码

1 绘制验证码图片

# app/utils.py
import random
def generate_str_code(length=4):"""随机生成验证码"""
import string
strings = string.ascii_letters + string.digits
return "".join(random.sample(strings, length))
def draw_code_image(str_code):
"""根据给丁的字符串验证码绘制验证码图片"""
# 引入绘图模块, Image表示画布对象; ImageDraw表示画笔对象; ImageFont表示字体对象;
from PIL import Image, ImageDraw, ImageFont
# 定义变量,用于画面的背景色、宽、高
bgcolor = (random.randrange(20, 100), random.randrange(20, 100), 255)
width = 100
height = 25
# 创建画面对象
im = Image.new('RGB', (width, height), bgcolor)
# 创建画笔对象
draw = ImageDraw.Draw(im)
# 调用画笔的point()函数绘制噪点
for i in range(0, 100):
xy = (random.randrange(0, width), random.randrange(0, height))
fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
draw.point(xy, fill=fill)
# 构造字体对象
font = ImageFont.truetype('/usr/share/fonts/wqy-microhei/wqy-microhei.ttc',
23)
# 构造字体颜色
fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))
for index, item in enumerate(str_code):
# print(5 +
(index*20))
draw.text((5 + (index*20), 2), item, font=font, fill=fontcolor)
return im
if __name__ == '__main__':
str_code = generate_str_code(length=5)
im = draw_code_image(str_code)
im.save('hello.png')

2 验证码视图

# views.pydef verifycode(request):
str_code = generate_str_code(length=5)
request.session['verifycode'] = str_code
im = draw_code_image(str_code)
#内存文件操作
"""
python2的为
# 内存文件操作
import cStringIO
buf = cStringIO.StringIO()
"""
# 内存文件操作-->此方法为python3的
import io
buf = io.BytesIO()
#将图片保存在内存中,文件类型为png
im.save(buf, 'png')
#将内存中的图片数据返回给客户端,MIME类型为图片png
return HttpResponse(buf.getvalue(), 'image/png')
def index(request):
return
render(request, 'verifycode/index.html')

3 配置URL

在app/urls.py中定义请求验证码视图的url
from django.conf.urls import url
from . import
views
urlpatterns = [
url(r'^$', views.index),
url(r'^verifycode/$', views.verifycode),
]
在project/urls.py中定义请求验证码视图的url:
urlpatterns = [
path('admin/', admin.site.urls),
url(r'code/', include('verify.urls')),
]

4 显示验证码

在模板中使用img标签,src指向验证码视图
扩展:点击“看不清,换一个”时,可以换一个新的验证码
为了能够实现提交功能,需要增加form和input标签

# templates/verifycode/index.html
<form method='post' action='/code/verifycodeValid/'>
<input type="text" name="vc">
<img id='verifycode' src="/code/verifycode/?1" alt="CheckCode"/>
<span id='verifycodeChange'>看不清,换一个</span>
<br><input type="submit" value="提交">
</form>
<script type="text/javascript"
src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script type="text/javascript">
$(function () {
$('#verifycodeChange').css('cursor', 'pointer').click(function () {
$('#verifycode').attr('src', $('#verifycode').attr('src') + 1)
});
});
</script>

5 验证

接收请求的信息,与session中的内容对比

# app/views.py
def verifycodeValid(request):
vc = request.POST['vc']
session_vc = request.session['verifycode']
if vc
== session_vc:
return HttpResponse('ok')
else:
return HttpResponse('no')

配置验证处理的url

# app/urls.py
urlpatterns = [
url(r'^$', views.index),
url(r'^verifycode/$', views.verifycode),
url(r'^verifycodeValid/$', views.verifycodeValid),
]

6 第三方验证码实现

可以在网上搜索“验证码”,找到一些第三方验证码提供网站,阅读文档,使用到项目中

  • 3
    点赞
  • 5
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值