视图层相关

视图层

三板斧

视图函数必须要返回一个HttpResponse对象。

The view app01.views.index didn't return an HttpResponse object. It returned None instead.

super(HttpResponse, self).__init__(*args, **kwargs)  # 都继承了HttpResponse父类

# render简单内部原理
from django.template import Template,Context
res = Template('<h1>{{ user }}</h1>')
con = Context({'user':{'username':'baba','password':123}})
ret = res.render(con)
print(ret)  # 后端进行打印
return HttpResponse(ret)  # 返回到前端
HttpResponse

返回字符串

render

返回HTML页面,并且在返回给浏览器之前还可以给HTML文件传值

redirect

重定向

JsonResponse对象

json数据格式

前后端数据交互需要使用到json作为过渡,实现跨语言的数据传输。

前端序列化 json格式
JSON.stringify() json.dumps()
JSON.parse() json.loads()
读源码掌握使用方法
  • 传递字典
import json
from django.http import JsonResponse  # JsonResponse对象
def ab_json(request):
    user_dic = {'username':'chuang哥好帅', 'password':'123', 'hobby':'sports'}
    # 先转成json格式字符串
    json_str = json.dumps(user_dic, ensure_ascii=False)
    """
        - def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
            allow_nan=True, cls=None, indent=None, separators=None,
            default=None, sort_keys=False, **kw):
        
        - If ``ensure_ascii`` is false, then the return value can contain non-ASCII
            characters if they appear in strings contained in ``obj``. Otherwise, all
            such characters are escaped in JSON strings.    
    """
    # 将字符串返回
    # return HttpResponse(json_str)
    return JsonResponse(json_str, json_dumps_params={'ensure_ascii':False})  # 继承了HttpResponse父类
  • 传递列表

只能直接序列化字典,序列化其他字符类型需要加safe参数。

from django.http import JsonResponse  # JsonResponse对象

def ab_json(request):
    l = [1, 2, 3, 4, 5]

    # Error Info:In order to allow non-dict objects to be serialized set the safe parameter to False.
    return JsonResponse(l, safe=False)  # 只能直接序列化字典,序列化其他字符类型需要加safe参数

Form表单上传文件及后端操作

1.method必须指定成post
2.enctype必须换成formdata

前端格式
<form action="" method="post" enctype="multipart/form-data">
    <p>username: <input type="text" name="username"></p>
    <p>file: <input type="file" name="file"></p>
    <input type="submit">
    
</form>
后端格式
def ab_file(request):
    if request.method == 'POST':
        # print(request.POST)  # 获取POST请求提交的键值对数据  拿不到文件数据
        # print(request.FILES)  # 获取文件数据
        # <MultiValueDict: {'file': [<InMemoryUploadedFile: 批量执行当前文件夹下的py文件.txt (text/plain)>]}>
        file_obj = request.FILES.get('file')  # 文件对象 get方法是拿到列表的最后一个
        print(file_obj.name)
        # 保存文件
        with open(file_obj.name, 'wb') as f:  # 注意是二进制数据
            for line in file_obj.chunks():  # .chunks()方法是切片的作用  不加也没问题
                f.write(line)

    return render(request, 'form.html')

request对象

request.method  # 获取请求方式
request.POST   # 获取POST请求提交的普通键值对数据,不包含文件数据
request.GET # 获取GET请求提交的数据
request.FILES  # 获取文件数据
request.body  # 原生的浏览器发过来的二进制数据 
request.path  # 获取用户访问的路由
request.path_info  # 
request.get_full_path()  # 获取完整的url及问号后面的参数 

# ******************************************************
# ******************************************************
print(request.path)  # /app01/ab_file/
print(request.path_info)  # /app01/ab_file/
print(request.get_full_path())  # /app01/ab_file/?username=zhangsan

FBV和CBV

django的视图层由两种形式构成:FBV和CBV

1、FBV基于函数的视图(Function base view)。

2、CBV基于类的视图(Class base view)。

采用CBV可以引入面向对象的思想对数据进行更高程度的封装。

CBV路由匹配
from django.contrib import admin
from app01 import views

urlpatterns = [
    # CBV路由
    url(r'^login', views.MyLogin.as_view())  # 必须调用类下的方法as_view
]
CBV后端程序

能够根据请求方式的不同直接匹配到对应的方法执行。

from django.views import View
class MyLogin(View):
    def get(self, request):
        return render(request, 'form.html')


    def post(self, requset):
        return HttpResponse('post方法')
CBV源码剖析

属性方法查找顺序

对象本身 ----> 产生对象的类中 ---> 类的父类

不知道函数内参数,可用(*args, **kwargs)进行匹配。

"""
	- 其中,args匹配位置参数, kwargs匹配关键字参数
"""

突破口在urls.py。

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # CBV
    url(r'^login/', views.MyLogin.as_view())  # 访问as_view()方法  函数名/方法名--->执行优先级最高
    # url(r'^login/',views.view)  FBV一模一样
    # CBV与FBV在路由匹配上本质是一样的 都是路由 对应 函数内存地址
]

"""
函数名/方法名  ---->   执行优先级最高


as_view()
        要么是被@staicmethod修饰的静态方法
        要么是被@classmethod修饰的类方法


    @classonlymethod
    def as_view(cls, **initkwargs):
        pass

"""

@classonlymethod
    def as_view(cls, **initkwargs):
        """
        cls就是我们自己写的类   MyCBV
        Main entry point for a request-response process.
        """
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)  # cls是我们自己写的类
            # self = MyLogin(**initkwargs)  产生一个我们自己写的类的对象
            return self.dispatch(request, *args, **kwargs)
            """
            以后你们会经常需要看源码 但是在看python源码的时候 一定要时刻提醒自己面向对象属性方法查找顺序
                先从对象自己找
                再去产生对象的类里面找
                之后再去父类找
                ...
            
            总结:看源码只要看到了self.XXX 
            	一定要问你自己当前这个self到底是谁
            """
        return view

# CBV的精髓   
def dispatch(self, request, *args, **kwargs):
    # 获取当前请求的小写格式 然后比对当前请求方式是否合法
    # get请求为例
    # post请求
    if request.method.lower() in self.http_method_names:  # 利用一个反射进行自动匹配
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        """
            反射:通过字符串来操作对象的属性或者方法
                handler = getattr(自己写的类产生的对象,'get',当找不到get属性或者方法的时候就会用第三个参数)
                handler = 我们自己写的类里面的get方法
            """
        else:
            handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)
        """
        自动调用get方法
        """
posted @ 2021-05-23 21:28  taxuebufeng  阅读(85)  评论(0)    收藏  举报