Django框架——路由分发名称空间虚拟环境视图层三板斧JsonResponse对象request获取文件FBV与CBVCBV源码剖析模版层

Posted XxMa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django框架——路由分发名称空间虚拟环境视图层三板斧JsonResponse对象request获取文件FBV与CBVCBV源码剖析模版层相关的知识,希望对你有一定的参考价值。

路由分发

# Django支持每个应用都可以有自己独立的路由层、静态文件、模版层。基于该特性多人开发项目就可以完全解耦合,之后利用路由分发还可以整合到一起

多个应用都有很多路由与视图函数的对应关系 这个时候可以拆分到各自的路由层中

使用路由分发之前 总路由直接是路由与视图函数的匹配
	url(r\'^index/\',views.index)
使用路由分发之后 总路由只按照应用名分配匹配方向
# 需要先在总路由中导入模块 include
from django.conf.urls import url,include

urlpatterns = [
    url(r\'^app01/\',include(\'app01.urls\')),
]

伪静态的概念

# 静态文件:写死的一些东西

# 伪静态
把一些动态的网页伪装成静态网页

\'\'\'为什么要伪装呢?\'\'\'
# 其实是因为静态的网页更加容易被搜索引擎抓取到
# 搜索引擎其实是一个巨大的爬虫程序,你在百度中搜索一个美女,百度拿着这个关键词去网络上去爬取数据,然后把爬到的数据处理好,返回到百度的页面

# 为了把我们的网页被搜索引擎更好的抓取到
seo----------------->免费的
sem------------------>收费的----------------->广告--------->rmb

名称空间

路由分发之后 针对相同的别名能否自动反向解析出不同的应用前缀
	默认情况下是无法直接识别应用前缀的 
# app01应用
def index(request):
    print(reverse(\'index_view\'))  # /app02/index/
    return HttpResponse(\'from app01 index\')
# app02应用
def index(request):
    print(reverse(\'index_view\'))  # /app02/index/
    return HttpResponse(\'from app02 index\')

虚拟环境

# 正常的开发,应该给每一个项目配备一个虚拟环境
\'\'\'一个虚拟环境相当于是一个纯净的python解释器!!!\'\'\'
# 针对一个新的项目,解释器上只装跟本项目有关的模块,其余没用的都不装

虚拟环境:能够针对相同版本的解释器创建多个分身 每个分身可以有自己独立的环境
    
pycharm创建虚拟环境:(每创建一个虚拟环境就相当于重新下载了一个全新的解释器)
命令行的方式:python -m venv pyvenv38
# python命令此处不支持多版本共存的操作 python27 python36 哪个环境变量在前 就创建哪个解释器版本
"""
    激活命令
    python -m venv py38venv
    cd py38venv
    cd Scripts
    activate  # 激活命令
    然后可以直接用
    deactivate  # 关闭命令
"""

注意:python命令此处不支持多版本共存的操作 python27 python36 python38
    命令行创建的
    	激活
        	activate
        关闭
        	deactivate
            
pip install --index-url http://mirrors.aliyun.com/pypi/simple/ django==1.11.11 --trusted-host mirrors.aliyun.com

视图层之必会三板斧

用来处理请求的视图函数都必须返回HttpResponse对象		完全正确
class HttpResponse:
    pass
return HttpResponse()

def render():
    return HttpResponse()
return render()

def redirect():
    redirect_class = 类(祖先有个类是HttpResponse)
    return redirect_class()
return redirect()

JsonResponse对象

"""
python中:
	序列化:	json.dumps()
	反序列化:	json.loads()
js中:
	序列化:	json.stringify()
	反序列化:	json.parse()
"""

from django.http import JsonResponse
def index_func(request):
    # 返回给浏览器一个json格式的字符串
    \'\'\'字典格式\'\'\'
    # user_dict = \'name\':\'jason老师\',\'age\':18
    \'\'\'列表格式\'\'\'
    user_list = [11,22,33,44]
    # import json
    # user_json = json.dumps(user_dict,ensure_ascii=False)
    # return HttpResponse(user_json)
    \'\'\'查看源码可知 字典序列化时需要再传一个参数json_dumps_params 通过关键字传参的方式转化成ensure_ascii=False\'\'\'
    # return JsonResponse(user_dict,json_dumps_params=\'ensure_ascii\':False)
    \'\'\'列表在序列化时需要把safe参数改成False\'\'\'
    return JsonResponse(user_list,json_dumps_params=\'ensure_ascii\':False,safe=False)

ps:以后写代码很多时候可能需要参考源码及所学知识扩展功能
	class JsonResponse():
        def __init__(self,data,json_dumps_params=None):
        		json.dumps(data,**json_dumps_params)
\'\'\'
**json_dumps_params接收关键字传参 把字典的形式转化成等于
例如 \'name\':\'jason\' ----->>> name=jason 
即可以把 \'ensure_ascii\':False ---->>> ensure_ascii=False
\'\'\' 

JsonResponse主要序列化字典 针对非字典的其他可以被序列化的数据需要修改safe参数为False
# 可以通过json.JSONEncoder查看可以被序列化的

视图层之request对象获取文件

# form表单上传文件需要满足的条件:
	1.请求方式需要是:post
    2.enctype必须是multipart/form-data
<form action="" method="post" enctype="multipart/form-data">

def func(request):
    if request.method == \'POST\':
        print(request.POST)  # 获取普通数据 (输入、选择)  <QueryDict: \'username\': [\'jason\'], \'hobby\': [\'basketball\', \'football\']>
        print(request.FILES)  # 获取文件数据(上传)  <MultiValueDict: \'file\': [<InMemoryUploadedFile: QQ图片20210106211056.jpg (image/jpeg)>]>
    file_obj = request.FILES.get(\'file\')
    print(file_obj.name)  # 获取文件名称
    with open(r\'%s\'%file_obj.name,\'wb\') as f:
        for line in file_obj:  # 文件对象支持for循环一行行读取内容
            f.write(line)
    return render(request,\'funcPage.html\')

# Django后端需要通过request.FILES获取文件类型的数据

视图层之FBV于CBV

FBV
	基于函数的视图
    def index(request):
        return HttpResponse对象
    
CBV 
	基于类的试图
    from django import views
    class MyLoginView(views.View):
        # 通过get请求方式会访问到这个方法
        def get(self,request):
            return HttpResponse(\'get\')
        
        # 通过post请求方式会访问到这个方法
        def post(self,request):
            return HttpResponse(\'post\')
    url(r\'^login/\',views.MyLoginView.as_view())
    # 会自动根据请求方法的不同自动匹配对应的方法并执行

CBV源码剖析(重要)

1.从CBV的路由匹配切入
	url(r\'^login/\',views.MyLoginView.as_view())
"""
1.类名点名字(名字的查找问题)
2.类名点名字并加括号调用(静态方法、绑定给类的方法)
	1.被@classmethod装饰器修饰的方法
	2.被@staticmethod装饰器修饰的方法
"""
# 我们在MyLoginView中并没有写as_view() 就会从继承的父类中查找
2.函数名加括号执行优先级最高 项目一启动就会自动执行as_view方法
	url(r\'^login/\',views.MyLoginView.as_view())
    path(\'login/\', views.view)  # CBV路由本质还是FBV 本质上放的还是函数的内存地址
3.浏览器地址栏访问login路由时 会出发view函数的执行
	1.产生我们自己编写类的对象
    2.对象调用dispatch方法(注意查找顺序)
4.研究父类中的dispatch方法
	获取当前请求方法并转小写 之后利用反射获取类中对象的方法并执行
    
class View:  # 继承的父类View
     @classmethod  # 绑定给类的方法 类调用是会把类当做第一个参数传进去
     def as_view(cls, **initkwargs):  # cls是我们自己写的类MyLoginView
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)  # 实例化一个对象(我们自己写的类产生的对象)
            return self.dispatch(request, *args, **kwargs)  # 对象点方法会先从产生这个对象的类中去查找 如果没有 就去父类中找 
        	\'\'\'此处可以在我们自己写的类中做拦截 自定义一个dispatch方法 写功能 这样就只会执行我们自定义的方法\'\'\'
        return view  # views.MyLoginView.as_view()调用方法返回值是view --->views.view --->访问路由就直接出发view函数的调用
    
    \'\'\'view函数执行完毕之后 返回值会调用dispatch方法\'\'\'
     def dispatch(self, request, *args, **kwargs):  # 父类View中的方法 此处的self是我们自己写的类产生的对象
        if request.method.lower() in self.http_method_names:
        	handler = getattr(self, request.method.lower(),self.http_method_not_allowed)  # request.method.lower() 请求方式的小写 例如:GET--->get POST--->post 如果自己写的类中没有这方法就会走后面那个报错
        	\'\'\'getattr(self,get)--->self.get\'\'\'
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
        # 对象点属性加括号调用这个方法
        \'\'\'self.get()\'\'\' 

模版层

"""
:主要与数据值相关
%%:主要与逻辑相关

Django的模版是自己写的 跟jinjia2不一样

1.针对需要加括号调用的名字 Django模版语法会自动加括号调用 你只需要写名字就行
2.模版语法的注释前端浏览器是无法查看的##
"""
1.模版语法传值
	def func(request):
        name = \'jason\'
        age = 18
	return render(request,\'demo02.html\',\'name\':namem,\'age\':age)
	# 传值方式1:精准传值 不浪费资源 针对多资源的传递书写会比较麻烦
    return render(request,\'demo02.html\',locals())
	# 传值方式2:将函数名称空间中所有的名字全部传递 名字过多并且不使用的情况下比较浪费资源
    
2.模版语法传值特性
	1.基本数据类型正常展示
    2.文件对象也可以展示并调用方法
    3.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)
    4.类名也会自动加括号调用
    5.对象则不会
    ps:总结针对可以加括号调用的名字模版语法都会自动加括号调用
    """
    基本数据类型
        <p> f </p>
        <p> i </p>
        <p> s </p>
        <p> l </p>
        <p> d </p>
        <p> t </p>
        <p> se </p>
        <p> b </p>
    文件类型
        <p> f_obj </p>
        <p> f_obj.read </p>
	函数
        <p> func1 </p> 调用函数
	类
        <p> MyClass </p>  内存地址
        <p> obj </p>  内存地址
        <p> obj.get_obj </p> 调用方法
        <p> obj.get_cls </p> 调用方法
        <p> obj.get_static </p>   调用方法
    """ 
3.模版语法之过滤器
	# 语法
	obj|filter__name:param  变量名字|过滤器名称:变量
    
    <p> i|add:1 </p>  <!--整型加法-->
    <p> s|add:\'baby\' </p>  <!--字符串拼接-->
    <p> l|length </p>  <!--列表长度-->
    <p> s|length </p>  <!--字符串长度-->
    <p> s|slice:\'1:4\'</p>  <!--切割 从1切到4-->
    <p> s|truncatechars:5 </p>  <!--展示前五个字符-->
    <p> s|truncatewords:3 </p>  <!--展示前三个单词 空格分隔-->
    <p> ctime|date:\'Y年-m月-d日 H时:i分:s秒\' </p>
    <p> file_size|filesizeformat </p>  <!--把数字转换成最佳单位的换算-->
    # 为了安全Django的模板中会对HTML标签和JS等语法标签进行自动转义
    # 我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义
    后端代码 --->>> h1 = \'<h1>哈哈哈哈</h1>\'
    <p> h1 </p>  # <h1>哈哈哈哈</h1> 默认不识别样式
    <p> h1|safe </p>  # 哈哈哈哈 会直接展示样式

Django学习——路由分发名称空间伪静态本地虚拟环境

路由分发 """ 简介 Django是专注于开发应用的,当一个Django项目特别庞大的时候 所有的路由与视图函数映射关系全部写在总的urls.py很明显太冗余不便于管理 其实Django中的每一个应用都可以有自己的urls.py,static文件夹,templates文件夹。 基于上述特点,使用D

以上是关于Django框架——路由分发名称空间虚拟环境视图层三板斧JsonResponse对象request获取文件FBV与CBVCBV源码剖析模版层的主要内容,如果未能解决你的问题,请参考以下文章

Django学习——路由分发名称空间伪静态本地虚拟环境

Django之路由(urls)层

digao表关系有无名分组反向解析路由分发

Django 基础一

django

django功能三