Django视图层

视图层

1. 视图函数

  • 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面。除此之外没有更多的要求了
  • 一般将视图放置在项目或应用程序目录中的名为views.py的文件中。

2. HttpRequest对象---请求

# 视图views.py request属性
def test(request):
    # request是<class 'django.core.handlers.wsgi.WSGIRequest'>类的对象
    print(type(request)) 
    from django.core.handlers.wsgi import WSGIRequest
    return HttpResponse('ok')

# request对象中包含了,请求报文中的信息,有如下方法或属性

HttpRequest.GET  # 一个类似于字典的对象,获取请求中GET信息

HttpRequest.POST  # 一个类似于字典的对象,获取请求中POST信息
注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:
request.POST.getlist("hobby")

# 注意
form表单,不写method时,默认是get请求
请求页面,请求数据时,使用GET
往后端提交数据时,使用POST

HttpRequest.body # 请求体信息,POST提交的信息,是一个bytes类型,b'请求体信息'

# 请求路径
HttpRequest.path # 只能获取?id=1之前的路径,只拿过路径,不拿数据
request.get_full_path()  # 可以获取完整的请求路径

HttpRequest.method # 获取请求的方法,一般为GET,POST

HttpRequest.FILES # 一个类似于字典的对象,包含所有的上传文件信息,如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中
FILES 中的每个键为<input type="file" name="" /> 中的name值对应数据。
注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会
包含数据。否则,FILES 将为一个空的类似于字典的对象。

3. HttpResponse对象---响应

  • 响应本质还是在使用HttpResponse
# 响应对象的三种形式
HttpResponse()
render()
redirect()

# render()
render(request,'test.html')是一个对象,它的类是:
<class 'django.http.response.HttpResponse'>

render(request,'test.html')的内容是:
<HttpResponse status_code=200, "text/html; charset=utf-8">

# redirect()
redirect('/test1/')   # 注意:'/test1/'是路由urls.py中,用户请求的路由路径,一般执行其他视图函数的其他页面,不能只想自己的路径的视图函数,否则为死循环

redirect('/test1/') 是一个对象,它的类是:
<class 'django.http.response.HttpResponseRedirect'>

redirect('/test1/') 的内容是:
<HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/test/">

# 301和302的区别
301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取
(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点

    不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;

  302表示旧地址A的资源还在(但是仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址

# 重定向原因:
(1)网站调整(如改变网页目录结构);
(2)网页被移到一个新地址;
(3)网页扩展名改变(如应用需要把.php改成.Html或.shtml)。
这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的
网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。

4. JsonResponse

  • 本质也是HttpResponse响应,不同的是,向前端返回json格式的数据
# views.py
# 方式一:
def test(request):
    import json
    data = {'name':'xut','age':18}  # 字典,列表都可以
    data1 = [1,2,3,4,5,6]
    return HttpResponse(json.dumps(data1))

# 方式二:
def test(request):
    from django.http import JsonResponse # Django做了封装模块,需要导入
    # data = {'name':'xut','age':19}
    data1 = [1,2,3,4,5,6]
    # return JsonResponse(data)
    return JsonResponse(data1,safe=False)  # 转化列表要注意,要将safe改为False

5. CBV和FBV

  • CBV:表示视图是基于类
  • FBV:表示视图是基于函数的

5.1 CBV视图基于类


# views.py
# 导入View模块
from django.views import View

# 定义一个类
class Test(View): # 继承View
    # dispatch方法,可以进行分发,添加额外的功能,类似于装饰器,比如登录后才能使用
    def dispatch(self,request,*args,**kwargs):
        print('分发路由前,可以添加额外内容')
        # 处理获取的get或post函数
        obj = super().dispatch(request,*args,**kwargs)
        print('分发路由后,可以添加额外内容')
        return obj # 架构处理后的get或post函数返回

    def get(self,request): # 需要传request参数
        obj = render(request,'test.html')
        print(type(obj))
        return obj

    def post(self,request):
        return HttpResponse('OK')

# urls.py路由中配置
# .as_view固定方法,得到的是个函数,来get就是get函数,来post就是post函数
re_path(r'test/',views.Test.as_view())

6. 简单的文件上传

# HTML模板
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--enctype="multipart/form-data"上传文件设置编码-->
<form action="" method="POST" enctype="multipart/form-data">
    <p>用户名:<input type="text" name="name"></p>
    <p>密码:<input type="text" name="password"></p>
    <p>文件:<input type="file" name="myfile"></p><!--name是文件名的key-->
    <p><input type="submit" value="提交"></p>
</form>
</body>
</html>

# views.py
from django.views import View

class Test(View):
    def get(self,request):
        obj = render(request,'test.html')
        print(type(obj))
        return obj

    def post(self,request):
        # ff是一个Django封装的文件对象;.FILES获取POST提交的数据
        ff = request.FILES.get('myfile') # myfile是表单提交的文件名
        file_name = ff.name # 文件对象的名字
    # 保存文件
        with open(file_name,'wb') as f:
            for line in ff.chunks():
                f.write(line)

        return HttpResponse('OK')

# 补充ff.chunks()方法的作用,是将收到的文件二进制,逐步传过来
def chunks(self, chunk_size=None):
    self.file.seek(0)
    yield self.read()
原文地址:https://www.cnblogs.com/itone/p/9594108.html