Loading

django之视图view

一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。

响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。

无论视图本身包含什么逻辑,都要返回响应。

CBV和FBV

FBV function based view

CBV class based view

# FBV版添加班级
def add_class(request):
    if request.method == "POST":
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")
    return render(request, "add_class.html")
# CBV版添加班级
from django.views import View


class AddClass(View):

    def get(self, request):
        return render(request, "add_class.html")

    def post(self, request):
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")

注意:

使用CBV时,urls.py中也做对应的修改:

# urls.py中
url(r'^add_class/$', views.AddClass.as_view()),

as_view源码流程

1.项目启动 加载ur.py时,执行类.as_view() ——》 view函数

2.请求到来的时候执行view函数:

  1. 实例化类 ——》 self

    ​ self.request = request

  2. 执行seld.dispatch(request, *args, **kwargs)

    1. 判断请求方式是否被允许:

    2. 允许 通过反射获取到对应请求方式的方法 ——》 handler(get,post...)

    3. 不允许 self.http_method_not_allowed ——》handler

    4. 执行handler(request,*args,**kwargs)

    返回响应 —— 》 浏览器

给视图加装饰器

FBV 加装饰器和普通函数一样,这里不再讲述。

def timer(func):
    def inner(*args, **kwargs):
        start = time.time()
        ret = func(*args, **kwargs)
        print("函数执行的时间是{}".format(time.time() - start))
        return ret
    return inner

CBV

from django.utils.decorators import method_decorator

1.加在方法上

@method_decorator(timer)
def get(self, request, *args, **kwargs):
    """处理get请求"""

2.加在dispatch方法上

使用CBV时要注意,请求过来后会先执行dispatch()这个方法,如果需要批量对具体的请求处理方法,如get,post等做一些操作的时候,
这里我们可以手动改写dispatch方法,这个dispatch方法就和在FBV上加装饰器的效果一样。
@method_decorator(timer)
def dispatch(self, request, *args, **kwargs):
    # print('before')
    ret = super().dispatch(request, *args, **kwargs)
    # print('after')
    return ret


@method_decorator(timer,name='dispatch')
class AddPublisher(View):

3.加在类上

@method_decorator(timer,name='post')
@method_decorator(timer,name='get')
class AddPublisher(View):

使用method_decorator和不使用的区别

1.传入装饰器函数的函数对象不同

2.inner函数获取参数不同

不使用:第一个参数为self,第二个为request对象

func——》<function AddPublisher.get at 0x000001FC8C358598>

args——》(<app01.views.AddPublisher object at 0x0001FC8C432C50>, <WSGIRequest: GET '/add_publisher/'>)

使用method_decorator之后:第一个参数为request对象

func——》<function method_decorator.<locals>._dec.<locals>._wrapper.<locals>.bound_func at 0x0015185F7C0D0>

args——》(<WSGIRequest: GET '/add_publisher/'>,)

request对象

当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象。
Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。

# 属性
request.methot   请求方式  GET
request.GET    url上携带的参数 QueryDict
request.POST   POST请求提交的数据 QueryDict
request.path_info   URL的路径    不包含ip和端口  不包含参数 /login/
request.META    请求头
request.body    请求体  b''
request.FILES   上传的文件
request.COOKIES  cookie
request.session	 session

# 方法
request.get_full_path()   URL的路径   不包含ip和端口 包含参数 /login/?name=xxx&pwd=123
request.is_ajax()    判断是都是ajax请求

上传文件实例

def upload(request):
    """
    保存上传文件前,数据需要存放在某个位置。默认当上传文件小于2.5M时,django会将上传文件的全部内容读进内存。
    从内存读取一次,写磁盘一次。
    但当上传文件很大时,django会把上传文件写到临时文件中,然后存放到系统临时文件夹中。
    :param request: 
    :return: 
    """
    if request.method == "POST":
        # 从请求的FILES中获取上传文件的文件名,file为页面上type=files类型input的name属性值
        filename = request.FILES["file"].name
        # 在项目目录下新建一个文件
        with open(filename, "wb") as f:
            # 从上传的文件对象中一点一点读
            for chunk in request.FILES["file"].chunks():
                # 写入本地文件
                f.write(chunk)
        return HttpResponse("上传OK")

form需要属性enctype="multipart/form-data"才可以传文件。

Response对象

HttpResponse,render, redirect

from django.shortcuts import render, redirect, HttpResponse
HttpResponse('字符串')    ——》  ’字符‘
render(request,'模板的文件名',{k1:v1})   ——》 返回一个完整的TML页面
redirect('重定向的地址')    ——》 重定向   Location : 地址

设置或删除响应头信息

response = HttpResponse()
response['Content-Type'] = 'text/html; charset=UTF-8'
del response['Content-Type']

属性

HttpResponse.content:响应内容
HttpResponse.charset:响应内容的编码
HttpResponse.status_code:响应的状态码

JsonResponse

HttpResponse的子类,专门用来生成JSON编码的响应。

from django.http import JsonResponse

response = JsonResponse({'foo': 'bar'})
print(response.content)

# b'{"foo": "bar"}'

默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。

response = JsonResponse([1, 2, 3], safe=False)
posted @ 2019-07-21 09:20  陌路麒麟  阅读(96)  评论(0编辑  收藏  举报