首页 > 其他分享 >django视图层详解

django视图层详解

时间:2022-12-13 22:00:45浏览次数:86  
标签:index request 视图 django json 详解 func def

内容概要

  1. 路由分发
  2. 名称空间
  3. 虚拟环境
  4. 视图层必会三板斧
  5. 视图层JsonResponse对象
  6. 视图层request对象获取文件
  7. 视图层FBV与CBV
  8. CBV源码剖析

内容详细

路由发分发

django支持每个应用都有自己独立的路由层,静态文件,模板层,视图层(默认),模型层(默认)基于该特性多人开发项目就可以完全解耦合,之后利用路由分发还可以整合到一起

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

基本使用

  1. 使用路由分发之前 总路由直接干了路由与视图函数的匹配

    path('index',views.index_func)
    
  2. 使用路由分发之后 总路由只按照应用名分配匹配方向

    path('user',include('user.urls'))
    path('home',include('home.urls'))
    

    image

    image

    user同样也是这个流程

    image

名称空间

路由分发之后 针对相同的别名能否自动反向解析出不同的应用前缀

​ 默认情况下是无法直接识别应用前缀的
例如下面情况
image

path('user',include('user.urls'),name='index')
path('home',include('home.urls'),name='index')

如果想要正常识别区分有两种方式

  1. 名称空间
    总路由

    path('user/', include(('user.urls', 'user'), namespace='user')),
    path('home/', include(('home.urls', 'home'), namespace='home')),
    

    后端使用

    print(reverse('home:index_func'))
    print(reverse('user:index_func'))
    

    image

    前端使用

    <h1 class="h1">{% url 'home:index_func' %}</h1>
    <h1 class="h1">{% url 'user:index_func' %}</h1>
    

    image

  2. 别名不冲突即可(推荐使用这种,比较简单)
    多个应用别名不冲突可以用应用名作为别名的前缀
    后端使用

    #home.urls.py
    path('index/',views.index_func,name='home_index_func'),
    
    
    #user.urls.py
    path('index/',
             views.index_func, name='user_index_func'),
    

    前端使用

    <h1 class="h1">{% url 'home_index_func' %}</h1>
    <h1 class="h1">{% url 'user_index_func' %}</h1>
    

虚拟环境

项目1需要使用:django1.11
python(3.8版本)

项目2需要使用:django2.22 pymysql requests

​ python(3.8版本)

项目3需要使用:django3.22 requests_html flask

​ python(3.8版本)

实际开发项目中我们只会给项目配备所需的环境,不需要的一概不配!!

虚拟环境:能够针对相同版本的解释器创建多个分身 每个分身可以有自己独立的环境

方式一:pycharm创建虚拟环境:(每创建一个虚拟环境就相当于重新下载了一个权限的解释器)

image

image

在创建虚拟环境缓慢,或者无法无法创建的时候,是因为虚拟环境会一些依赖,要从国外下载,比较慢,或者网络原因造成下载失败,

建议手动永久换源,具体步骤请看这里pip模块永久换源 - clever-cat

第二种方式

cmd终端配置

建议使用python3.8以上的版本因为自带了虚拟模块,3.8以下的需要安装模块

需要注意的是python命令此处不支持多版本共存的操作 python27 python36 python38,

如果使用会报以下错误

python38 -m venv py38

image

下面这样就创建成功了

python -m venv py38

image

虚拟环境的激活与关闭
激活

首先要进入虚拟目录的Scripts目录中然后执行下面命令

active

image

下面是激活后的效果

image

image

关闭

deactive

image

安装模块

如果出现--trusted-host就使用下面命令

pip install --index-url http://mirrors.aliyun.com/pypi/simple/ django==1.11.11 --trusted-host mirrors.aliyun.com

正常情况直接就算下面这样直接安装成功
image

视图层必会三板斧

用来处理请求的视图函数都必须返回HttpResponse对象

完全正确

HttpResponse

底层
class HttpResponse(HttpResponseBase):
    pass


使用
def index_func(request):
    return HttpResponse('哈哈哈')

render

底层
def render(request, template_name, context=None, content_type=None, status=None, using=None):
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)
所以render底层也是返回HttpResponse对象

使用
def index_func(request):
    return render(request, 'home/index.html')

redirect

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

使用
def index_func(request):
	return redirect()

JsonResponse对象

from django.shortcuts import HttpResponse
def show_func(request):
    a1 = {'name': '张三', 'pwd': '123', 'age': 18}
    import json
    re_data = json.dumps(a1)  # 取消转义
    return HttpResponse(re_data)

image

from django.http import JsonResponse
def show_func(request):
    a1 = {'name': '张三', 'pwd': '123', 'age': 18}
	# 返回给浏览器一个json格式的字符串
    return JsonResponse(a1,json_dumps_params={'ensure_ascii':False})

image

以后写代码很多时候可能需要产靠源码及所学知识扩展功能

class JsonResponse(HttpResponse):
    """
    An HTTP response class that consumes data to be serialized to JSON.

    :param data: Data to be dumped into json. By default only ``dict`` objects
      are allowed to be passed due to a security flaw before EcmaScript 5. See
      the ``safe`` parameter for more information.
    :param encoder: Should be a json encoder class. Defaults to
      ``django.core.serializers.json.DjangoJSONEncoder``.
    :param safe: Controls if only ``dict`` objects may be serialized. Defaults
      to ``True``.
    :param json_dumps_params: A dictionary of kwargs passed to json.dumps().
    """

    def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
                 json_dumps_params=None, **kwargs):
        if safe and not isinstance(data, dict):
            raise TypeError(
                'In order to allow non-dict objects to be serialized set the '
                'safe parameter to False.'
            )
        if json_dumps_params is None:
            json_dumps_params = {}
        kwargs.setdefault('content_type', 'application/json')
        data = json.dumps(data, cls=encoder, **json_dumps_params)
        super().__init__(content=data, **kwargs)

下面是json模块可以序列化的数据类型

	+-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict              | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str               | string        |
    +-------------------+---------------+
    | int, float        | number        |
    +-------------------+---------------+
    | True              | true          |
    +-------------------+---------------+
    | False             | false         |
    +-------------------+---------------+
    | None              | null          |
    +-------------------+---------------+

这里是djngo基于json模块又给我们加了一些封装的数据类型

class DjangoJSONEncoder(json.JSONEncoder):
    """
    JSONEncoder subclass that knows how to encode date/time, decimal types, and
    UUIDs.
    """

JsonResponse主要序列化字典 怎对非字典的其他可以被序列化的数据需要修改safe参数为False

def show_func(request):
    l1 = [1, 2, 3, 4, 5, '哈哈', '123']
    return JsonResponse(l1, json_dumps_params={'ensure_ascii': False})

image

def show_func(request):

    l1 = [1, 2, 3, 4, 5, '哈哈', '123']
    return JsonResponse(l1,
        json_dumps_params={'ensure_ascii': False},safe=False)

image

视图层request对象获取文件

form表单携带文件类型的数据需要做到以下几点

  1. method必须是post
  2. enctype必须是multipart/form-data

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

单文件上传

后端代码


if request.method.lower() == 'post':
    res_obj = request.FILES.get('file')  # 获取文件对象需要与前端 file name的属性值一致
    print(res_obj.name)  # 获取文件对象里面的文件名字
    #保存文件
    import os
    from django06 import settings
    with open(os.path.join(settings.BASE_DIR, 'home', 'templates', res_obj.name), 'wb') as f:
        for i in request.FILES.get('file'):
            f.write(i)
            

前端代码

<form action="" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="file">
    <button>btuuon上传</button>
    <input type="submit" value="submit上传">
</form>

多文件上传

后端代码

if request.method.lower() == 'post':
	res_obj = request.FILES.getlist('file')
    for file_obj in res_obj:
        print(file_obj.name)
        import os
        with open(os.path.join(settings.BASE_DIR, 'home', 'templates', file_obj.name), 'wb') as f:
            for i in file_obj:
                f.write(i)

前端代码

<form action="" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="file" mutiple>
    <button>btuuon上传</button>
    <input type="submit" value="submit上传">
</form>

image

上传成功

视图层FBV与CBV

FBV

基本函数的视图

def index(request):return HttpResponse对象

CBV

基于类的视图

from django import views
class Myfunc(views.View):
    def get(self, request):
            return HttpResponse('from CBV get function')

    def post(self, request):
            return HttpResponse('from CBV post function')
path('view/', views.MyView.as_view())

image

image

CBV源码剖析(重点)

  1. 切入点CBV的路由匹配切入

    path('view/', views.MyView.as_view())
    
    1. 类点点名字(名字查找顺序问题)
    2. 类名点名字并且加括号调用不穿参数(静态方法,绑定给类的方法)
  2. 函数名加括号执行优先级最高项目一启动就会自动执行as_view方法

    image

    然后就变成了下面的形式

    path('login/', views.view)  # CBV路由本质还是,FBV
    
  3. 我们在地址栏访问view路由匹配成功会自动加括号views.view函数

    1. 产生我们自己编写类的对象
    2. 对象调用dispatch方法(注意查找顺序)
      image
  4. 研究父类中的dispatch方法
    获取当前请求方法并转小写 之后利用反射获取类中的对应的方法并执行

    class View:
         @classmethod
         def as_view(cls, **initkwargs):
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)
                return self.dispatch(request, *args, **kwargs)
         def dispatch(self, request, *args, **kwargs):
             handler = getattr(self, request.method.lower())
             return handler(request, *args, **kwargs)
    

    image

标签:index,request,视图,django,json,详解,func,def
From: https://www.cnblogs.com/clever-cat/p/16980769.html

相关文章