视图层:三板斧问题,JsonResponse序列化,form表单上传文件,request对象的其他几个方法,CBV的书写和FBV的写法,CBV的源码分析.模板层:变量之分配,过滤器

发布时间 2023-08-01 15:01:45作者: 毓见

视图层

三板斧问题

# 在视图函数中写函数跟普通函数不太一样
# djagno中使用的局部的request
def index(request):
    pass

def func(request):
    pass

'''所有的视图函数不能够没有返回值,并且返回值还必须是HttpResponse对象'''

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

# 其实我们的三板斧方法返回的都是HttpResponse对象



# 在flask中request使用的是全局的request
from ... import request
def index():
    pass

def func():
    pass

# 所有的视图函数都使用全局的request对象,会不会乱套? 不会乱套,如何做到不乱套的? 在源码中揭晓.

JsonResponse序列化

# json格式的数据?
主要就是实现跨语言数据传输

# 现在实现跨语言数据的传输使用的都是json,在以前使用的是xml

# 微信支付朝微信的后端发送参数的时候,使用的就是xml

json格式的数据特点:
{"username":"kevin","age":18}
{"username":"kevin","age":18}

# 之前学的是如何序列化的?
import json
json.dumps     -------------》 JSON.stringify()
json.loads		-----------》JSON.parse() 

# 在js中是如何做的
JSON.stringify()
JSON.parse()  # 对象

# 在Django中又该如何去序列化


# js中的对象
obj = new Object() # {}
obj = {} # {}

obj.username = 'kevin' # {'username':'kevin'}

consolo.log(obj.username)

from django.http import JsonResponse
def index(request):
    # return render(request, 'index.html')
    # return HttpResponse("index")
    # 追代码----》点进去这个方法去看源码
    # return render(request, "index.html", context={})
    # return redirect()
    # d = {'username': 'kevin哈喽', 'age': 18}
    # In order to allow non-dict objects to be serialized set the safe parameter to False.
    l = [1, 2 , 3, 4]
    # 如何去序列化
    import json
    # d_json = json.dumps(d,ensure_ascii=False) # 字符串
    # res = JsonResponse(d_json)
    # print(res)  # <JsonResponse status_code=200, "application/json">
    # return HttpResponse(d_json)
    # return HttpResponse(d_json)
    return JsonResponse(l,safe=False)

form表单上传文件

# form表单上传文件的前提:
1. 请求方式必须是post
2. enctype必须是form-data

request对象的其他几个方法

request.GET
request.POST
request.FILES

request.path_info  #  /ab_request/ 
reqeust.path       #  /ab_request/ 
request.get_full_path() # /ab_request/  /ab_request/?username=kevin&age=11
request.body # 现在先不学,它能够接收浏览器发过来的二进制数据,BBS项目中学

C(class)BV的书写和F(function)BV的写法

# 目前写的都是FBV:function based view 基于函数的视图
# 在视图文件中书写类 CBV:class based view 基于类的视图

postman的官网地址:https://www.postman.com/downloads/
apizza的挂网地址:http://www.apizza.net/

# 所有的类必须继承django的view类
from django.views import View


class MyLogin(View):
    # 类里面的方法名字不能够随便写,目前只能写get post等
    # 访问这个地址必须是get请求方式
    def get(self, request):
        # get() takes 1 positional argument but 2 were given
        print("get")
        return HttpResponse("get")

    # 访问这个方法必须是psot请求方式
    # 通过form表单发送post请求
    # 出了form表单,我们还可以使用工具来模拟
    def post(self,request):
        print("post")
        return HttpResponse("post")

CBV的源码分析

# 我们第一次看Django的源码,面试题:你都看过Django的哪些源码,简单说说?

# CBV的源码、settings的源码、权限、频率、认证的、签发token的源码

看源码的步骤是先找到源码的入口
CBV的入口在哪里呢?
path('login/', views.MyLogin.as_view()),

views.MyLogin.as_view()

"""
	类名可以调用哪些方法:
		1. 方法被@classmethod装饰器修饰的方法
			类名来调用类方法有什么特殊之处:
				会把类名自动当成第一个参数传递给方法的第一个形参cls
				对象调用方法把对象自己当成第一个参数传给方法的第一个形参self
			
		2. 被@staticmethod装饰器修饰的方法
"""
# 回头复习面向对象的方法调用

# 第一步
@classonlymethod
    def as_view(cls, **initkwargs):
        # cls:MyLogin
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.setup(request, *args, **kwargs)
            if not hasattr(self, 'request'):
                raise AttributeError(
                    "%s instance has no 'request' attribute. Did you override "
                    "setup() and forget to call super()?" % cls.__name__
                )
            return self.dispatch(request, *args, **kwargs)
    
        return view
    
# 第二步:
path('login/', View.view),

# 第三步:
当请求来的时候,开始匹配路由login,就会调用View.view()

# 第四步
        def view(request, *args, **kwargs):
            # self = MyLogin(**initkwargs)
            self = cls(**initkwargs)
            """
                self: MyLogin()
            """
            return self.dispatch(request, *args, **kwargs) # 这句话是最重要的
 # 第五步:self.dispatch(request, *args, **kwargs) 
# 第六步:找到了View类里面的dispatch方法
第七步:
	def dispatch(self, request, *args, **kwargs):
        	# getattr: 反射
            # 反射
            # getattr setattr delattr hasattr
            # handler = getattr(self, 'get', self.http_method_not_allowed)
            # handler = getattr(self, 'post', self.http_method_not_allowed)
            # handler就是方法名,对象
            # hander = get
            # hander = post
            # hander = self.http_method_not_allowed
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
    

# 问题:如何让我写的CBV类只支持get请求或者只支持post请求?
源码是用来看的,不是用来改的,有时候也能够改,但是你不行,你这个阶段先不要想着改人家源码的


class MyLogin(View):
    http_method_names = ['get',]
    # 类里面的方法名字不能够随便写,目前只能写get post等
    # 访问这个地址必须是get请求方式
    def get(self, request):
        # get() takes 1 positional argument but 2 were given
        print("get")
        return HttpResponse("get")

模板层

模板变量之分配

# 模板中取值一定使用的是句点符.
# 模板中的函数一定不能够加括号,他们会自动帮你加括号调用

模板之过滤器

Django自带的过滤器有好几十、但是我们没必要全部记住,只需要记住几个就行了
语法:
	{{ obj|过滤器名称:参数 }}  变量名字|过滤器名称:变量

案例:
	default
	length
	{#{{ res|default:'你很好啊' }}#}
    {#{{ res|length }}#}
    {#{{ res|filesizeformat }}#}
    {#{{ res|date:'Y-m-d' }}#}
    {#{{ res|truncatechars:9}}#}
    {#{{ res|safe }}#}

{{ res }}
二进制的位移