day 52

day52 视图层 模版层

01.视图层

  1. 小白三板斧

    1. HttpResponse
    2. render
    3. redirect
  2. JsonPesponse

    1. JsonResponse是HttpResponse的子类,专门用来生成json编码的响应

    2. 前后端分离

      1. 前后端通常情况下,通过json的字符串(字典)来进行数据交互

      2. 后端只需要写好相应的url接口,前端访问这个接口

      3. 只需要一个 返回一个大字典+开发文档(用来告诉前端工程师这个接口会返回那些数据)即可

      4. 前后端序列化和反序列化的方法

        python后端								js前端
        json.dumps()						 JSON.stringify
        json.loads()						 JSON.parse
        
    3. 向前端发送json字符串

      from django.http import JsonResponse
      dic = {'name':'jason'}
      # 让不默认转码为ascii
      # json_str = json.dumps(dic,ensure_ascii=False)
      return JsonResponse(dic,json_dumps_params={'ensure_ascii':False})
      
    4. JsonResponse是默认序列化字典用的,序列化其他类型需要添加一个safe = False参数

      l = [1,2,3,4,5,6,7,]
      return JsonResponse(l,safe=False)
      
  3. FBV与CBV

    1. FBV:基于函数的视图

    2. CBV:基于类的视图

      1. 必须要基础View

        from django.views import View
        class MyLogin(View):
            def get(self, request):
                return render(request, "add_book.html")
        
            def post(self, request):
                return render(request, 'book_list.html')
        
      2. url.py路由写法

        url(r'^login/',views.Mylogin.as_view())
        
      3. CBV源码的实现流程

        # 第一步
        url(r'^login/',views.Mylogin.as_view())
        # url(r'^login/',views.view) 调用as_view()产生了一个闭包函数view
        
        # 第二步 当路由匹配上后执行view函数
        return self.dispatch(request, *args, **kwargs) # 调用dispatch函数
        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
        def dispatch(self, request, *args, **kwargs):
          # 判断当前请求方式在不在默认的八个方法内
          # 1.先以GET请求为例
          if request.method.lower() in self.http_method_names:
            # 利用反射去我们自己定义类的对象中查找get属性或者是方法  getattr(obj,'get')
            # handler = get方法
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
          else:
              handler = self.http_method_not_allowed
          return handler(request, *args, **kwargs)  # 调用get方法
        
      4. CBV添加装饰器

        1. 直接写

          @outter  # 1.直接写
          def get(self, request):
            print('我是MyLogin里面的get方法')
            return render(request, 'login.html')
          
        2. 推荐写法

          1. 内部

            from django.utils.decorators import method_decorator
            
            @method_decorator(outter)  # 1.推荐写法
            	def get(self,request):
            		print('我是MyLogin里面的get方法')
            		return render(request,'login.html')
            
          2. 外部

            @method_decorator(outter)  # 对类内部所用函数添加装饰器
            @method_decorator(outter,name='post')  # 针对某一功能添加
            class MyLogin(View):
            
          3. 当要对class内部函数添加一些功能时

            @method_decorator(outter)
            def dispatch(self, request, *args, **kwargs):  # 如果你想在视图函数执行之前 做一些操作 你可以在你的CBV中定义dispatch方法来拦截
            		# 可以在此处对这个类单独做一些操作
              return super().dispatch(request,*args,**kwargs)
            
  4. django

02.模版层

  1. 模版语法

    {{ }} 变量相关  
    {% %} 逻辑相关
    
  2. 模版语法传值

    1. 给html的两种方式

      1. 指名道姓 当需要传递的变量名太多

      2. locals

        # locals() 会将当前所在的名称空间中所有的名字传递给页面
        return render(request, 'test.html', locals())
        
    2. 能给html传值的数据类型

      1. 八种基本数据类型都可以
      2. 函数名:会自动加()调用展示返回值,模版语法不支持函数传参
      3. 类名:会自动加()产生一个对象
      4. 对象;可以传递
      5. 只要是能够加括号调用的,传递到html页面上都会自动加()调用
  3. 过滤器 |

    1. 模版语法提供了一些内置方法,帮助快速处理数据

    2. 模版语法

      1. 会自动将|左边的数据当作过滤器的第一个参数
      2. 将:右边的当作第二个参数传入
      <!--前端-->
      <p>模板语法之过滤器   会自动将|左边的数据当前过滤器的第一个参数传入 :右边的当做第二个参数</p>
      
      # 后端
      from django.utils.safestring import mark_safe
      sss2 = "<h2>我的h2标签</h2>"
      res = mark_safe(sss2) # 将字符串变为html内部文本,激活标签
      
    3. 过滤器

      1. 统计长度

        <p>统计长度(如果无法统计默认返回0):{{ s|length }}</p>
        
      2. 加法运算

        <p>加法运算(内部异常捕获 支持数字相加 字符串拼接 都不符合返回空):{{ n|add:f }}</p>
        
      3. 切片操作

        <p>切片操作 顾头不顾尾 也支持步长:{{ l|slice:'0:5:2' }}</p>
        
      4. 自动转成文件大小格式

        <p>自动转成文件大小格式:{{ file_size|filesizeformat }}</p>
        
      5. 截取文本内容(字符)

        <p>截取文本内容(字符) 截取五个字符 三个点也算:{{ s|truncatechars:8 }}</p>
        
      6. 截取文本内容(单词)

        <p>截取文本内容(按照空格计算) 截取五个单词 三个点不算 :{{ s1|truncatewords:5 }}</p>
        
      7. 判断是否有值

        <p>判断是否有值(有值展示值本身 没值展示默认值):{{ is_value|default:'is_value变量名指向的值为空' }}</p>
        
      8. 展示带有标签的文本

        <p>展示带有标签的文本:{{ sss|safe }}</p>
        <p>默认情况下 是不会自动帮你转换成前端html标签 防止恶意攻击</p>
        
    4. 标签:逻辑相关的一堆代码

      1. for循环,if

        <!--for if联合使用-->
        {% for foo in l %}
        	{% if forloop.first %}
        		<p>这是我的第一次</p>
        	{% elif forloop.last %}
        		<p>这是最后一次了啊</p>
        	{% else %}
        		<p>{{ foo }}</p>
        	{% endif %}
        	{% empty %}
        		<p>当for循环的对象是空的时候会走</p>
        {% endfor %}
        

        for循环中可用的参数

        Variable Description
        forloop.counter 当前循环的索引值(从1开始)
        forloop.counter0 当前循环的索引值(从0开始)
        forloop.revcounter 当前循环的倒序索引值(从1开始)
        forloop.revcounter0 当前循环的倒序索引值(从0开始)
        forloop.first 当前循环是不是第一次循环(布尔值)
        forloop.last 当前循环是不是最后一次循环(布尔值)
        forloop.parentloop 本层循环的外层循环
      2. 模版语法的取值只有一种方式,. 句点符

        <p>模板语法的取值 只有一种方式  统一采用句点符  (.)</p>
        	<p>{{ comp_dic.hobby.2.2.age }}</p>
        
      3. with 起别名,只能在with内部使用

        <p>当你的数据是通过比较复杂的点点点获取到的后续又需要经常使用 你可以给该数据起别名 别名只能在with内部使用</p>
        {% with comp_dic.hobby.2.2.age as age  %}
            <p>{{ age }}</p>
            <p>{{ comp_dic.hobby.2.2.age }}</p>
        {% endwith %}
        
    5. 自定义过滤器和标签

      1. 必须要有三步准备

        1. 在应用名下新建一个templatetags的文件夹

        2. 在该文件夹内新建一个人一名称的py文件

        3. 在该文件下写下面的两句话

          from django.template import Library
          register = Library()
          
        4. 自定义过滤器

          # 自定义过滤器  跟默认的过滤器一样 最多只能接受两个参数
          @register.filter(name='baby')
          def index(a,b):
              return a + b
          
          <!--自定义过滤器的使用-->
          <p>自定义过滤器的使用</p>
          {% load mytag %}  <!--要像导入模块一样导入-->
          {{ 1|baby:1  }}
          {{ 1|baby:100  }}
          <!--自定义的过滤器可以在逻辑语句中使用-->
          
        5. 自定义标签

          # 自定义标签   可以接受任意多个参数
          @register.simple_tag(name='mytag')
          def mytag(a,b,c,d):
              return '%s?%s?%s?%s'%(a,b,c,d)
          
          <p>自定义标签的使用 可以接受多个参数 参数与参数之间必须空格隔开</p>
          {% load mytag %}
          {% mytag 'a' 'b' 'c' 'd' %}
          {% load mytag %}
          <!--自定义的标签不能再逻辑语句中使用-->
          
        6. 自定义inclusion_tag

          1. 是一个函数,能给接收外界传入的参数,然后传递给html页面
          2. 页面上获取数据 渲染 完成之后
          3. 将渲染好的页面 放到调用 inclusion_tag 的地方
          # 自定义inclusion_tag
          @register.inclusion_tag('mytag.html',name='xxx')
          def index666(n):
              l = []
              for i in range(n):
                  l.append('第%s项'%i)
              return locals()  # 将l直接传递给mytag.html页面
          
          <p>自定义inclusion_tag的使用  当你需要使用一些页面组件的时候 并且该页面组件需要参数才能够正常渲染 你可以考虑使用inclusion_tag</p>
          {% load mytag %}
          {% xxx 5 %}
          
  4. 模版的继承

    1. 先在想要继承的页面上通过block划定想要修改的区域 在继承之后就可以使用划定的区域

      {% block content %}  <!--content为给该区域命名,好在子页面中查找不同的位置-->
      <!--每个页面不同的地方-->
      {% endblock %}
      先在页面上利用block划定你以后可能想改的区域
      
      <!--继承之后  就可以通过名字找到对应的区域进行修改-->
      {% extends 'home.html' %}  <!--导入要继承的页面-->
      
      {% block content %}
      修改模板中content区域内容
      {% endblock %}
      
    2. 模版页面上的block区域越多 页面的可扩展性越强

    3. 建议一个模版页面最少要有三个block区域

      1. css区域
      2. html代码区域,可设置多个block
      3. js区域
      4. 有了这三个区域,就能够实现每张页面都能有自己的css和js
      {% extends 'home.html' %}	 <!--导入要继承的页面-->
      
      {% block css %}
      	<style>
      		p {
      			color: green;
      		}
      	</style>
      {% endblock %}
      
      {% block content %}
      <p>login页面</p>
      <!--你还可以在子页面上继续沿用父页面的内容-->
      {{ block.super }}  <!--可以重复多个-->
      {{ block.super }}
      {% endblock %}
      
      {% block js %}
      	<script>
      		alert('login')
      	</script>
      {% endblock %}
      
  5. 模版的导入

    1. 将html页面当做模块导入,可以将常用的组件如导航条,页尾信息等保存在单独的文件中
    {% include 'bform.html' %}
    
原文地址:https://www.cnblogs.com/luocongyu/p/11939037.html