django基础五

视图

FBV: function based view 基于函数的视图
CBV: class based view 基于类的视图

 

CBV视图写法

#url.py
from app01 import views
url(r'^add_class/',views.add_class),
#views.py
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视图写法

#url.py
from app01 import views
url(r'^add_class/',views.AddClass.as_view())
#view.py
from django.views import View   #先导入django的View类
​
class AddClass(View):
    
    def get(self,request):    #处理get请求
        return render(request,'ass_class.html')
    
    def post(self,request):
        class_name = request.POST.get('class_name')
        models.Classes.create(name=class_name)
        return redirect('/class_list/')

as_view的执行流程

1.项目启动 加载url.py时,执行类.as_view()    ——》  生成view函数,
    url(r'add_class/',views.AddClass.as_views())↓↓↓↓↓↓
    url(r'add_class/',view)         每个url生成view函数都不一样
​
2.请求到来的时候执行view函数:
    '1.实例化类  ——》 在view函数中 self = cls(**initkwargs)实例化对象
        self.request = request 
        view函数return self.dispatch(request, *args, **kwargs)
    '2.执行self.dispatch(request, *args, **kwargs)
        1.判断请求方式是否被允许:
             1. 允许    通过反射获取到对应请求方式的方法   ——》 handler
             2. 不允许   self.http_method_not_allowed  ——》handler
            dispatch函数return handler(request, *args, **kwargs)
        2.执行handler(request,*args,**kwargs)
                返回响应   —— 》 浏览器
 

给视图加装饰器

#FBV
#FBV本身就是一个函数,所以与普通函数加装饰器一样
import time
def wrapper(func):
    def inner(*args,**kwargs):
        start = time.time()
        ret = func(*args,**kwargs)
        print(time.time()-start)
        return ret
    return inner
​
@wrapper
def st_add(request):
    return render(request,'st_add.html',{'k1':v1,'k2':v2})
#CBV加装饰器
import time
from django.utils.decorators import method_decorator
​
def wrapper(func):  #装饰器函数
    def inner(*args,**kwargs):
        start = time.time()
        ret = func(*args,**kwargs)
        print(time.time()-start)
        return ret
    return inner
----------------------------------------------------------------------
#方法一
class AddClaass(View):
    
    @method_decorator(wrapper)   #相当于加有参数的装饰器
    def get(self,request):
        return render(request,'add_class.html',{'k1':v1})
    
    @method_decorator(wrapper)
    def post(self,request):
        class_name = request.POST.get('class_name')
        models.Classes.objects.create(name=class_name)
        return redirect('/class_list/')
----------------------------------------------------------------------   
#方法二
#所有类绑定方法都要通过dispatch方法执行,那么直接给dispatch方法加装饰器,所有方法都有了
class AddClaass(View):
    
    @method_decorator(warppper)     给dispatch方法加装饰器,所有方法都加
    def dispatch(self, request, *args, **kwargs):
        ret = super().dispatch(request, *args, **kwargs)  #执行父类的dispatch方法完成任务
        return ret
    
    def get(self,request):
        return render(request,'add_class.html',{'k1':v1})
    
    def post(self,request):
        class_name = request.POST.get('class_name')
        models.Classes.objects.create(name=class_name)
        return redirect('/class_list/')
----------------------------------------------------------------------   
#方法三
#所有类绑定方法都要通过dispatch方法执行,那么直接给dispatch方法加装饰器,所有方法都有了
class AddClaass(View):
    
    @method_decorator(warppper)     #给dispatch方法加装饰器,所有方法都加这样更加省事
    def dispatch(self, request, *args, **kwargs):
        start = time.time() #不加装饰器直接写
        ret = super().dispatch(request, *args, **kwargs)  #执行父类的dispatch方法完成任务
        print('{}'.format(time.time()-start)) #不加装饰器直接写
        return ret
    
    def get(self,request):
        return render(request,'add_class.html',{'k1':v1})
    
    def post(self,request):
        class_name = request.POST.get('class_name')
        models.Classes.objects.create(name=class_name)
        return redirect('/class_list/')
---------------------------------------------------------------------- 
#方法四
@method_decorator(wrapper,name='post') #加在类上这样更加灵活
@method_decorator(wrapper,name='get')
class AddClaass(View):
    
    def get(self,request):
        return render(request,'add_class.html',{'k1':v1})
    
    def post(self,request):
        class_name = request.POST.get('class_name')
        models.Classes.objects.create(name=class_name)
        return redirect('/class_list/')
 

form表单上传文件

#上传文件的注意事项
1.form表单的属性   enctype="multipart/form_data"
2.input 的  type="file"
3.request.FILES.get('xx') #input框的name
-----------------------------------------------------------------------
# html模板
<form action="" method="post" enctype="multipart/form_data">
    {% csrf_token %}
    上传文件: <input type="file" name="file">
    <button>提交</button>
</form>
-----------------------------------------------------------------------
#视图
def upload(request):
    if request.mathod == "POST":
        file = request.FILES.get('file')
        path = r'D:\PY\progect\untitled\file\%s'%(file.name)
        with open(path,'wb')as f:
            for i in file.chunks():
                f.write(i)
        print(f'{file.name}上传完成')
        return HttpResponse("上传完成")
    return render(request,'upload.html')

request对象的属性和方法

#request对象的属性
request.method              # 请求方式    GET  POST
request.GET                 # url上携带的参数需要 .get()来取
request.POST                # POST请求提交的数据(参数)需要 .get()来取
request.path_info           # 请求路径信息(不包含IP和端口也不包含查询参数) /index/
request.body                # 请求体的数据 get请求请求体为空
request.COOKIES             # cookie
request.session             # session
request.FILES               # 上传的文件
request.META                # 请求头的信息(一个大字典)
-----------------------------------------------------------------------
#request对象的方法
request.get_full_path()     # 完整的路径信息 只包含路径和参数不包含IP和端口
request.is_ajax()           # 判断是否是ajax请求
request.get_host()          # 获取主机的IP和端口

response对象

返回模式返回内容
HttpResponse('字符串') 字符串
render(request,'模板文件名',{'k1':v1}) 完整的页面(把参数传进HTML文件替换后渲染)
redirect('要跳转的地址') 重定向,返回响应头Location:url在重新发送个get请求
#redirect可以传递一个视图的名称
def my_view(request):
    ...
    return redirect('add_book',foo='bar')
#redirect可以传递一个具体的网址
def my_view(request):
    ...
    return redirect('/add_book/')
#redirect可以传递一个完整的网址
def my_view(request):
    ...
    return redirect('http://baidu.com/')

JsonResponse对象

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

#用法
from django.http import JsonResponse
import json
​
def json_data(request):
    data = {'name':'alex','age':73} 
    return JsonResponse(data) #只能认识字典类型
    #想要认识其他类型的可以这么写
    # return JsonResponse(data,safe=False)
    #如果页面直接返回HttpResponse(data) 则只能取到 nameage 这样的字符串
posted @ 2019-09-05 17:08  微狐  阅读(111)  评论(0)    收藏  举报