Django之view视图处理(FBV,CBV,装饰器,前后端交互各种数据类型和响应,请求头相关信息)【四】

目录


Django后端交互各种数据类型和响应

实战Django前后端的交互各种数据类型及响应:https://blog.csdn.net/Burgess_zheng/article/details/86539836

  • 前端单选框数据提交和后端接收

前端

<form method="POST" action="/submit/" enctype="multipart/form-data">
    {% csrf_token %}
    {#单选框#}
    <div>
        男:<input type="radio" name="gender" value="1">
        女:<input type="radio" name="gender" value="2">
        同:<input type="radio" name="gender" value="3">
    </div>
    <input type="submit" name="提交">
</form>

后端

def submit_handle(request):
    # radio(单选框)接收数据格式如下:
    gender = request.POST.get('gender')
    print('gender: ',gender)
  • 前端多选框数据提交和后端接收

前端

<form method="POST" action="/submit/" enctype="multipart/form-data">
    {% csrf_token %}
    {#多选框#}
    <div>
        男:<input type="checkbox" name="favor" value="11">
        女:<input type="checkbox" name="favor" value="12">
        同:<input type="checkbox" name="favor" value="13">
    </div>
    <input type="submit" name="提交">
</form>

后端

def submit_handle(request):
    # checkbox(多选框)接收数据如下:
    favor = request.POST.getlist('favor')
    print('favor: ',favor)
  • 前端select单选下拉框数据提交和后端接收

前端

<form method="POST" action="/submit/" enctype="multipart/form-data">
    {% csrf_token %}
    {#select下拉框#}
    <div>
        <select name="city">
            <option value="sz">深圳</option>
            <option value="gz">广州</option>
            <option value="cs">潮汕</option>
        </select>
    </div>
    <input type="submit" name="提交">
</form>

后端

 

def submit_handle(request):
    # select(单选下拉框)接收数据如下:
    city = request.POST.get('city')
    print('city: ',city)
  • 前端select多选下拉框数据提交和后端接收

前端

<form method="POST" action="/submit/" enctype="multipart/form-data">
    {% csrf_token %}
    {# select序多选下拉框#}
    <div>
        <select name="city_mul" multiple>
            <option value="sz">深圳</option>
            <option value="gz">广州</option>
            <option value="cs">潮汕</option>
        </select>
    </div>
    <input type="submit" name="提交">
</form>

后端

def submit_handle(request):
    # select(多选下拉框)接收数据如下:
    city_mul = request.POST.getlist('city_mul')
    print('city_mul:',city_mul)

 

  • 前端文件数据提交和后端接收

前端

<form method="POST" action="/submit/" enctype="multipart/form-data">
    {% csrf_token %}
    {# 文件接收 #}
    <div>
         <input type="file" name="file_name"/>
    </div>
    <input type="submit" name="提交">
</form>

后端

def submit_handle(request):
    # files(上传文件)接收数据如下:
    obj = request.FILES.get('file_name')  # 获取用户上传过来整个文件
    import os
    file_path = os.path.join('%s\\upload'%os.path.dirname(os.path.abspath(__file__)), obj.name)  # 在上传的文件名加上一个upload路径
    f = open(file_path, mode="wb")  # 二进制写入方式在upload目录创建一个的文件,文件名为调取客户上传的文件名
    for i in obj.chunks():  # 文件都是块组成的,obj.chunks 获取该文件的所有块导入i
        f.write(i)  # 循环把块写入f文件
    f.close  # 写完关闭掉文件
    print('file:',obj)     #打印显示该对象(FILES获取是整个文件 不是文件名,显示和文件名一样)
    # print(type(obj))     #打印该对象的类型(结果类型是一个类的对象,证明是文件)
    # print(obj.name)      #打印显示该对象的名字(这就是文件名了)
    # print(type(obj.name)) #打印显示该对象的名字的类型(结果类型是字符串
    # print(obj,type(obj),obj.name,type(obj.name))  #以上是分开打,其实逗号隔开打都可以

 

  • 交互总结:

获取数据、返回数据的命令参数
    1.获取数据的几种方式
        request.method
        request.GET
        request.POST
        request.FILES
        request.path_info
        request.COOKIES
        reqeust.body    #所有内容的原生数据

    2.获取checkbox等多选的内容
        request.POST.getlist()
        request.GET.getlist()

        #所以分成两类
        request.body  #用户请求的原生数据,以字符串形式存放
        
            request.POST
            request.FILES
            #django帮我们做了一部分处理(以上2种),从body提取出来的字符串转换成字典

            request.xxxx.getlist
            #django帮我们做了一部分处理(以上1种),从body提取出来的字符串转换成列表

            request.GET  #通过url,不是通过body的
           
            request.PUT
            request.DELECT
            request.MOVE
            #django对上面3种没有做处理,所以我们操作以上3种的时候就需要通过request.body获取原生数据:字符串形式

            request.Meta
            #出了数据外,请求头相关的信息,如:判断用户是PC端还是移动端

            request.method(POST、GET、PUT..)
            request.path_info
            request.COOKIES

     3.接收上传文件,注意:模板文件html的form标签必须做特殊设置:enctype="multipart/form-data"
        obj = request.FILES.get('file')
        obj.name    #取该文件名
        obj.size       #取该文件的字节大小
        obj.chunks  #取该文件的块
        file_path = os.path.join('%s\\upload'%os.path.dirname(os.path.abspath(__file__)), obj.name)  #当前文件的目录下的upload目录和接收文件名进行拼接成文件路径
        f = open(obj.name,mode= 'wb') #如果该路径文件存在就打开,不存在就创建
        for item in obj.chunks():
            f.write(item) #写入文件
        f.close()     #关闭文件
            
     4.返回给用户的几种方式                             
        return render(request,'模板路径.html',{'list':[1,2,3,4],'dict': {'k1':'v1','k2':'v2'} })  #返回给用户指定经过模板渲染后的html
        retune redirect(’url路径’)        #跳转到指定url
        retune HttpResponse(‘字符串’)  #直接返回给用户字符串

       response = HttpResponse(a)
       response.set_cookie(‘key’:’value’)  #设置客户端cookie
       response[‘name’] = ‘bur’   #设置客户端响应头
       return response

后端接收形式示例

def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == "POST":
# radio(单选框)接收数据格式如下:
        #v = request.POST.get('gender')
        #print(v)

# checkbox(多选框)接收数据如下:
        #v = request.POST.getlist('favor')
        #print(v)

# select(单选下拉框)接收数据如下:
        #v = request.POST.get('city')
        #print(v)

# select(多选下拉框)接收数据如下:
        #v = request.POST.getlist('city')
        #print(v)

#files(上传文件)接收数据如下:
        obj = request.FILES.get('fafafa')#获取用户上传过来整个文件
        import os
        file_path = os.path.join('upload',obj.name)#在上传的文件名加上一个upload路径
        f = open(file_path, mode="wb") #二进制写入方式在upload目录创建一个的文件,文件名为调取客户上传的文件名
        for i in obj.chunks():  #文件都是块组成的,obj.chunks 获取该文件的所有块导入i
            f.write(i) #循环把块写入f文件
        f.close #写完关闭掉文件
        # print(obj)     #打印显示该对象(FILES获取是整个文件 不是文件名,显示和文件名一样)
        # print(type(obj)) #打印该对象的类型(结果类型是一个类的对象,证明是文件)
        # print(obj.name)  #打印显示该对象的名字(这就是文件名了)
        # print(type(obj.name)) #打印显示该对象的名字的类型(结果类型是字符串
        # print(obj,type(obj),obj.name,type(obj.name))  #以上是分开打,其实逗号隔开打都可以
        return render(request, 'login.html')

    else:
        # PUT,DELETE,HEAD,OPTION....(目前用不到)
        return redirect('/index/')

FBV,CBV and FBV装饰器,CBV装饰器

实战Django之views视图的(FBV,CBV,FBV装饰器,CBV装饰器) https://blog.csdn.net/Burgess_zheng/article/details/86545000

  • FBV (function base views )

url:
    re_path('fbv', views.fbv),
    # url(r'^fbv', views.fbv),

func:
    def fbv(requset):
        return render(requset,'fbv_Cbv.html')

  • CBV (class base views)

url:

re_path('cbv', views.Cbv.as_view()),
# url(r'^cbv', views.Cbv.as_view()),

class:

from django.views import View
#导入View模块
class Home(View):  #使用类处理需要继承View(view是Home的父类,Home是子类)  
    def get(self,request): #自动识别,如果用户请求方式:get,那么自动调用该方法执行结果
        print(request.method)
        return render(request, 'home.html')

     def post(self,request):
        print(request.method)#自动识别,如果用户请求方式:post,那么自动调用该方法执行结果
        return render(request, 'home.html')

自定义类继承的View源码有多种接收方式:

具体跳转实战以后就可以知道执行顺序,其实知道个dispathch方法也没什么用,如果你想要在views类或者函数处理前接收用户请求完全可以使用信号或者中间件,当然在跳转实战的url就可以做到dispathch的作用

  • FBV and CBV 装饰器

装饰器如果不同请跳转:Python之实战装饰器拆解 https://blog.csdn.net/Burgess_zheng/article/details/85757740

#实现装饰器的需求:
#高阶函数+嵌套函数=装饰器

#你必须要知道装饰器需要具备哪些知识:
#一、函数既是变量  二、2.高阶函数(2种原则)  三、3.嵌套函数

#一、函数既是变量的知识:
#(1)Python内存对变量的存放原理和回收机制
#(2)pyhotn对函数的函数体存放原理,和回收机制
#(3)匿名函数是没有名字的函数体
#(4)Python执行规则
#(5)局部变量

#二、高阶函数是什么?需要具备以下两点:
#(1)把一个函数名当做实参传给另外一个函数的函数
# (可以做到的效果:在不修改被装饰函数源代码的情况下为其添加了功能)
#(2)返回值中包含函数名
#(可以做到的效果:不修改函数的调用方式和源代码也可以添加功能)

#三、嵌套函数是什么?
# 嵌套函数和局部变量是一样的原理,局部函数

#装饰器需求:
#(1) (装饰器)全局函数里的嵌套函数(局部函数)必须返回本身函数体内存地址给全局函数作为形参
#(2)  被装饰的函数必须作为实参给(装饰器)全局函数作为形参
#(3)(装饰器)的局部函数的形参最好以参数组出现。

#装饰器auth
def auth(func):
    def inner(reqeust,*args,**kwargs):
        v = reqeust.COOKIES.get('username111')  # 获取客户端cookies文件里面的key为username111的值
        if not v:  # 假如该v是空
            return redirect('/cmdb/login/')
        return func(reqeust,*args,**kwargs)
    return inner #该函数inner的函数体作为形参


#被装饰函数index
@auth
def index(request):
    #获取当前已经登录的用户名
    v = request.COOKIES.get('username111')#获取客户端cookies文件里面的key为username111的值
    return render(request,'index.html',{'current_user':v})

#CBV装饰器
#被装饰类Order(三种装饰模式)
#第一种装饰类里面某个指定函数
from django.views import View
class Order(View):
    from django.utils.decorators import method_decorator
    @method_decorator(auth)
    def get(self,request):
        v = request.COOKIES.get('username111')  # 获取客户端cookies文件里面的key为username111的值
        return render(request, 'index.html', {'current_user': v})
    def post(self,request):
        v = request.COOKIES.get('username111')  # 获取客户端cookies文件里面的key为username111的值
        return render(request, 'index.html', {'current_user': v})

#第二种装饰类里面所有的函数(基于该类的父类的dispatch方法)
from django.views import View
class Order(View):
    from django.utils.decorators import method_decorator
    @method_decorator(auth)
    def dispatch(self, request, *args, **kwargs):
        return super(Order, self).dispatch(request, *args, **kwargs)

    def get(self,request):
        v = request.COOKIES.get('username111')  # 获取客户端cookies文件里面的key为username111的值
        return render(request, 'index.html', {'current_user': v})
    def post(self,request):
        v = request.COOKIES.get('username111')  # 获取客户端cookies文件里面的key为username111的值
        return render(request, 'index.html', {'current_user': v})

#第二种装饰类里面所有的函数(基于该类的父类的dispatch方法)
from django.views import View
from django.utils.decorators import method_decorator
@method_decorator(auth,name='dispatch')
class Order(View):
    def get(self,request):
        v = request.COOKIES.get('username111')  # 获取客户端cookies文件里面的key为username111的值
        return render(request, 'index.html', {'current_user': v})
    def post(self,request):
        v = request.COOKIES.get('username111')  # 获取客户端cookies文件里面的key为username111的值
        return render(request, 'index.html', {'current_user': v})

请求头相关信息

def index(request):
    from django.core.handlers.wsgi import WSGIRequest
    #request根据该类实例化来的(ctrl+右键点击WSGIRequest:查看该类所有方法)
    print(type(request))   #打印找到对象的类
                           #request是个对象,所以request.xx是调取类方法
    print(request.environ) #environ:封装了所有用户请求信息(字符串)
    #如果使用获取原生数据,那么自己就需要拿字符串一个一个处理
    #django内部会把经常使用的值,做一部分处理,如request.POST等
    #如果django一些功能做了处理,那么我们直接使用该功能 .POST  .GET
    #同理如果django没有帮我们处理的功能,我们需要调用,那么就使用原生语句

    #request.POST   request.GET   request.COOKIES
    #如果想要获取原生数据,或者django没有处理的一些原生数据,
    #environ,是一个字典存放了用户请求的信息,
    # 循环获取下自己想要的原生数据,如下:
    for k,v in request.environ.items():
        print(k,v,sep='|')
    v = request.environ['SERVER_PORT']
    #获取用户请求的原生数据,根据指定的key获取value
    print(v)
    return HttpResponse('OK')

environ该参数就是接收用户提交的信息
以下为所有用户请求信息(原生数据,蓝色为key)   
通过Python原生语句 request.environ['key'] 可以获取到相对应的内容
蓝色注释为用户请求相关,红色为服务端相关

插入Django知识:

如果是django接收上面的数据,Django会在请求体里面获取了数据,然后在取请求头的content-type的类型是否是:application/url-form-encod.. 
如果是的该类型,会把请求体的use=burgess&pwd=123 该数据进行提取并且字符串类型转换成Queryset类型对象放到request.POST里面,所以我们django获取post请求的格式: request.POST 获取到的是<Queryset :{ 'use':'burgess','pwd': '123'}>
request.POST[‘use’] 获取到的是burgess   request.POST[‘feewf’] 获取到的是none
request.POST.get(‘use’) 获取的是burgess request.POST.get(‘dsdf’) 报错没值
request.POST.get(‘dsdf’,’xxx’)  如果获取的dsdf没有存在,获取的就是xxx
 

下一篇:Django之模板HTML(模板渲染(字符,列表,字典),HTML继承母版(extends ,extends), templatetags(simple_tag,filter))【五】https://blog.csdn.net/Burgess_zheng/article/details/86547739

猜你喜欢

转载自blog.csdn.net/Burgess_zheng/article/details/86539387
今日推荐