• Day 58 django 视图层 模板层


    Day 58 django

    1、网页伪静态

    将动态网页伪装称静态网页 从而提升网页被搜索 收录的概率

    表现形式就是网址看着像是一个具体的文件路径

    path('index.htm',views.index)
    
    • 1

    2、视图层

    2.1、视图函数返回值 问题

    视图函数必须返回一个HTTPResponse对象
    注意HTTPResponse 其实是一个类
    HttpResponse

    class HttpResponse(HttpResponseBase):
    
    • 1

    render

    def render(request, template_name, context=None, content_type=None, status=None, using=None):
        #查看源码 发现 返回的是 HttpResponse
        return HttpResponse(content, content_type, status)
    
    • 1
    • 2
    • 3

    redirect

    def redirect(to, *args, permanent=False, **kwargs):
        
        #查看 源码 得知 redirect 中 三元表达式  返回 其中的结果 然后我们继续深入 
      	redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
        return redirect_class(resolve_url(to, *args, **kwargs))
    #深入 后发现 他最后 还是 继承了 HttpResponse
    class HttpResponseRedirectBase(HttpResponse):
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.2、视图函数返回json格式数据

    利用json模块 先序列化 然后 返回

    from django.http import JsonResponse  # 可以导入 jsonRespons 直接可以 序列化字典
    def func2(request):
       user_dict = {'name': 'jason老师', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
       json_str= json.dumps(user_dict,ensure_ascii=False)
       return HttpResponse(json_str)
       return JsonResponse(user_dict)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    查看JsonResponse 源码 查找 中文 取消编码 方法

    ef __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 数据 在 序列化的时候 后面 就会 得到一个 关键字 参数 那么 这个字典 就可以 是 {'ensure_ascii':False}
            #然后 一关键字参数 传给dumps 来 取消 编码
            data = json.dumps(data, cls=encoder, **json_dumps_params)
            super().__init__(content=data, **kwargs)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    序列化 非字典类型数据 还需要指定 safe参数 为False

     JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False})
    
    • 1

    2.3、form表单携带文件数据

    form表单 需要具备的条件

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

    获取表单数据

    def func1(request):
        if request.method=='POST':
            print(request.POST)
    
        return render(request,'login.html')
    
    
    #获取到的 只是拿到文件 名称 并未 文件数据
    <QueryDict: {'file': ['微信图片_20220824171248.jpg'], '提交': ['提交']}>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    获取 文件携带 数据的操作

    • 前端 必要操作
      enctype="multipart/form-data"

      <form action="/func1/" method="post" enctype="multipart/form-data">
      
      • 1
    • 后端操作

      request.FILEs

      print(request.FILES) #获取 列表 套对象
      file_obj=request.FILEs.get('file')
      
      • 1
      • 2
    • 获取 的是文件迭代器对象 可以点name 方法 获取文件名 然后通过 for循环 写入

      def func1(request):
          if request.method=='POST':
              print(request.FILES)
              file_pbj=request.FILES.get('file')
              with open(file_pbj.name,'wb')as f:
                  for data in file_pbj:
                      f.write(data)           
      	return render(request,'login.html')
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

    2.4、FBV与CBV

    FBV:基于函数的视图

    #views
    def func(request):
        return HttpResponse()
    #urls
    path('index/',views.index)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    CBV:基于类的视图

    #views
    from django import views
    
    class Myviews(views.View):
        def get(self,request):
            return HttpResponse('CBV GET方式')
        def post(self,requset):
            return HttpResponse('CBV,POST方式')
        
    #urls
    path('func3/',views.Myviews.as_view()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • CBV会自动根据请求方式的不同匹配类中定义的方法并自动执行

    CBV 源码分析

    1. 源码分析路口

      path('func3/',views.Myviews.as_view()
      
      • 1
    2. 绑定类的as_view方法

        @classonlymethod		
        def as_view(cls, **initkwargs):  # 通过 装饰语法 将其定义为类的属性方法
            ...
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)
                ...
                return self.dispatch(request, *args, **kwargs)
            ...
           	return view  #最后 返现 返回的是 view函数
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    3. 发现CBV路由匹配的本质 跟FBV是一致的

      			#都是 点 函数的形式
      path('func/', views.view)  #都是 通过访问路由 然后 调用函数
      
      • 1
      • 2
    4. 访问到func 触发view函数执行

      def view(request, *args, **kwargs):
          self = cls(**initkwargs)  #类产生一个对象 就是 我们写的类产生的对象, cls 是我们自己写的类 点 as_views 传进来的
          ...
          #最后 对象 点 dispatch 先从 对象本身找该方法 没有 再到父类找
          return self.dispatch(request, *args, **kwargs)
      
      • 1
      • 2
      • 3
      • 4
      • 5
    5. 研究dispatch方法

      # http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
      def dispatch(self, request, *args, **kwargs):
          #  请求方式小写字符串  在不在 后面这个列表里面面
          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)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

    3、模板层

    3.1、模板语法传值

    方式一:指名道姓的传

    return render(request,'modal.html',{'name':name})
    
    • 1

    方式二:关键字locals()

    return render(request,'modeal.html',locals())
    
    • 1

    3.2、模板语法值得范围

    基本数据类型直接传递使用

    函数名:
    函数名的传递会自动加括号执行 并将返回值展示到页面上
    注意函数如果有参数则不会执行也不会展示 模板语法不支持有参函数

    类名:
    类名得传递也会自动加括号产生对象 并展示到页面上

    对象:
    对象得传递则直接使用即可

    规律:
    模板语法会判断每个名字是否可调用 如果可以则调用

    3.3、模板语法过滤器

    类似于python的内置函数

    <p>同级长度:{{ s|length }}</p>   
    <p>数字加法运算:{{ i|add:100 }}</p>   
    <p>字符串拼接:{{ s|add:'python' }}</p>  
    <p>日期转换:{{ res|date:'Y-m-d H:i:s' }}</p>
    <p>文件大小:{{ file_size|filesizeformat }}</p>
    <p>数据切片:{{ l|slice:'0:4' }}</p>   
    <p>字符截取:(按字符个数截取 三个点 算一个){{ s|truncatechars:6 }}</p>   #超出范围 会返回完整的数据 
    <p>单词截取:(三个点不算 按空格截取){{ s|truncatewords:2 }}</p>
    <p>语法转义:{{ script|safe }}</p>   # 重点
    <p>语法转义 (后端转):{{ script_mak }}</p>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    后端语法转义

    from django.utils.safestring import mark_safe
    script_mak=mark_safe('

    我在干饭

    '
    ) <p>语法转义 (后端转):{{ script_mak }}</p>
    • 1
    • 2
    • 3
    • 4

    3.4、模板语法标签

    类似于 python中流程控制

    django 模板语法中符号 就两个 {{}} {% %}
    需要使用数据的时候{{}}
    需要使用方法的时候{% %}

    分支结构

    # if...elif..else
    {% if '' %}  # 条件 一般是模板语法传过来的数据 直接写名字就行 不需要双大括号
        <p>哈哈哈</p>
    {% elif '2'%}
        <p>嘿嘿嘿</p>
    {% else %}
        <p>呵呵呵</p>
    {% endif %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    for循环

    {% for re in s %}
        {% if forloop.first %}
            <p>这是第一次</p>
         {% elif forloop.last %}
            <p>这是最后一次</p>
        {% else %}
             <p> {{ re }}</p>
        {% endif %}
        {% empty %}
            <p>是空的无法循环</p>
    {#    {{ forloop }}#}
    {% endfor %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.5、自定义标签、过滤器、inclusion_tag

    如果想自定义 必须做以下三件事

    1. 在应用下创建名为templatetags文件夹

    2. 在该文件夹传进啊任意名称的py文件

    3. 在该py文件内编写自定义相关代码

      from django.template import Library
      register = Library()
      
      • 1
      • 2

    3.6、自定义过滤器

    在temp latetags 文件夹下创建任意名称py文件

    过滤器 至多只能有两个函数

    from django.template import Library
    
    register = Library()
    
    
    # 自定义 过滤器
    @register.filter(name='myfilter')
    def my_add(a, b):
        return a + b
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    引用过滤器

    {% load mytags %}  #引用
    {{ i|myfilter:1 }}
    
    • 1
    • 2

    3.7、自定义标签函数

    @register.simple_tag(name='mt')
    def func(a, b, c, d):
        return a + b + c + d
    
    • 1
    • 2
    • 3

    引用函数

    {% load mytags %}
    {% mt 1 2 3 4 %}
    
    • 1
    • 2

    3.8、自定义inclusion_tag

    @register.inclusion_tag(filename='it.html')
    def index(n):
            html = []
            for i in range(n):
                html.append('第%s页'%i)
            return locals()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    引用函数

    3.9、模板继承

    将要 变动的 内容 利用block包起来

    #模板 继承 母板内容
    {% extends 'html文件名' %} # 继承了 就可以 获取的 该文件 所有内容
    
    {% block 名字 %}
    模板内容
    {% endblock %}
    
    
    {% block 名字 %}  #创建标记
    子板内容
    {% endblock %}
    一般情况下母板中至少应该有三个区域使得扩展性更高!!!
    
    {% block css %}
    {% endblock %}
    {% block content %}
    {% endblock %}
    {% block js %}
    {% endblock %}
    {子板中 可以使用母版的内容}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    模板 导入到 母版

    将html页面的某个部分当做模块的形式导入使用
    {% include 'menu.html' %}  #只能是 部分
    
    • 1
    • 2
  • 相关阅读:
    【ARM】使用模板编写dht11温湿度linux驱动程序
    【递归、搜索与回溯算法】第四节.50. Pow(x, n)和2331. 计算布尔二叉树的值
    文件上传漏洞详解
    Java中利用OpenCV进行人脸识别
    ubuntu18.04 LTS卸载qtcreator-10.0.2
    .Net core web api 上传图片代码
    本质安全设备标准(IEC60079-11)的理解(一)
    [附源码]计算机毕业设计springboot茶叶销售微信小程序
    VMware+Ubuntu安装过程,含秘钥
    elasticSearch+kibana+logstash+filebeat集群改成https认证
  • 原文地址:https://blog.csdn.net/weixin_71967396/article/details/126692477