zoukankan      html  css  js  c++  java
  • Day 52 Django视图层/模板层

    Django视图层

    JsonResponse

    前后端分离

    ​ 前后端数据交互,该如何进行?

    ​ 通常情况下前后端数据交互采用的都是json的字符串(字典),后端只需要写好相应的url接口,前端访问你的这个接口,你只需要返回一个大字典+开发文档即可,用来告诉前端工程师,你的这个接口能返回那些数据

    def index(request):
        user_dic = {'name': 'Tiny', 'pwd': '123'}
        # 如何让json不自动帮你对中文进行转码
        json_str = json.dumps(user_dic, ensure_ascii=False)  # ensure_ascii是dumps方法的一个参数,默认为True
        return HttpResponse(json_str)
    

    利用JsonResponse

    from django.http import JsonResponse
    
    def index(request):
        user_dic = {'name': 'Tiny', 'pwd': '123'}
        return JsonResponse(user_dic, json_dumps_params={'ensure_ascii': False})
    # JsonResponse默认是序列化字典用的,如果你想序列化其他数据类型(json模块能够序列化的),你需要加一个safe参数(safe=False)
    

    FBV与CBV

    FBV: 基于函数的视图

    CBV: 基于类的视图

    我们之前一直在写的路由就是FBV,它的写法很简单

    urlpattern = [
        url(r'^login/', views.login),
    ]
    

    CBV的写法与FBV有点不同

    urlpattern = [
        url(r'login/', views.MyLogin.as_view())
    ]
    

    视图层类的书写

    from django.views import View
    class MyLogin(View):
        def get(self, request):
            return render(request, 'login.html')
    
        def post(self, request):
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
            return HttpResponse(name, pwd)
    

    CBV的源码解析

    为什么CBV能够根据请求方式的不同 自动执行不同的方法???

    1. 先会调用as_view方法
    2. 在as_view函数中有一个闭包函数view会被执行
    3. 在view函数中会生成一个我们建立的类的对象(用self表示)
    4. 会给类对象放入所需要的参数
    5. 会执行self.dispatch(会在view方法名称空间中寻找dispatch,找不到会去类的名称空间中找,而dispatch方法就在类的名称空间中)
    6. dispatch函数中利用反射的方法去获取类中的方法(get,post等八个方法),如果没有则报错
    7. 返回得到的函数handler(request, *args, **kwargs)调用的结果

    装饰器用法

    首先我们先来写一个简单的装饰器

    import time
    from functools import wraps
    
    def outter(func):
    	@wraps(func)
        def inner(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            end_time = time.time() - start_time
            print(f'函数执行时间:{end_time}')
            return res
        return inner
    

    现在我们给类中的方法加上装饰器,如果一个一个方法加的话会非常麻烦,可以使用以下方法

    from django.views import View
    from django.utils.decorators import method_decoratior
    
    class MyLogin(View):
        @method_decorator(outter)
        def dispatch(self, request, *args, **kwargs):
            return super().dispatch(request, *args, **kwargs)
        
        def get(self, request):
            return render(request, 'login.html')
    
        def post(self, request):
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
            return HttpResponse(name, pwd)
    

    method_decoratior还可以指定给某个方法装上装饰器

    Django模板层

    模板语法

    只有两种书写格式

    {{}} 变量相关

    {%%} 逻辑相关

    模板传值

    可以传到前端的数据类型

    1. python基本数据类型全部支持传值

    2. 给HTML页面传递函数名的时候,模板语法会自动加括号调用该函数,并且将函数的返回值当做展示依据(模板语法不支持函数传参,也就意味着你传给html页面的只能是无参函数)

    3. 传递类名时,会自动加括号实例化产生对象

    4. 传递对象或者对象方法时,会自动加括号调用

    总结: 只要是能够加括号调用的 传递到html页面上都会自动加括号调用

    过滤器

    内置方法(|)

    模板语法也给你提供了一些内置的 方法,帮你快速的处理数据

    {#<p>统计长度(如果无法统计默认返回0):{{ s|length }}</p>#}
    			{#<p>加法运算(内部异常捕获 支持数字相加 字符串拼接 都不符合返回空):{{ n|add:f }}</p>#}
    			{#<p>切片操作 顾头不顾尾 也支持步长:{{ l|slice:'0:5:2' }}</p>#}
    			{#<p>判断是否有值(有值展示值本身 没值展示默认值):{{ is_value|default:'is_value变量名指向的值为空' }}</p>#}
    			{#<p>自动转成文件大小格式:{{ file_size|filesizeformat }}</p>#}
    			{#<p>截取文本内容(字符) 截取五个字符 三个点也算:{{ s|truncatechars:8 }}</p>#}
    			{#<p>截取文本内容(按照空格计算) 截取五个单词 三个点不算 :{{ s1|truncatewords:5 }}</p>#}
    			{#<p>默认情况下 是不会自动帮你转换成前端html标签 防止恶意攻击</p>#}
    			{#<p>展示带有标签的文本:{{ sss|safe }}</p>#}
    			{#<p>展示带有标签的文本:{{ sss1|safe }}</p>#}
    

    前后端取消转义

    前端

    |safe

    后端

    from django.utils.safestring import mark_safe
    
    sss = "<h2>我是h2标签</h2>"
    res = mark_safe(sss)
    

    标签的流程控制

    if判断

    {% if n %}
        <p>s有值</p>
    {% else %}
        <p>s没有值</p>
    {% endif %}
    

    for循环

    <p>{% for li in lis %}
    	<p>{{ forloop }}</p>
    {% endfor %}
    

    forloop的作用

    {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 5, 'revcounter0': 4, 'first': True, 'last': False}
    
    {'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 4, 'revcounter0': 3, 'first': False, 'last': False}
    
    {'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 3, 'revcounter0': 2, 'first': False, 'last': False}
    
    {'parentloop': {}, 'counter0': 3, 'counter': 4, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False}
    
    {'parentloop': {}, 'counter0': 4, 'counter': 5, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
    

    for和if联用

    {% for li in lis %}
        {% if forloop.first %}
        	<p>我是第一个</p>
        {% elif forloop.last %}
        	<p>我是最后一个</p>
        {% else %}
        	<p>{{ li }}啦啦啦</p>
        {% endif %}
        {% empty %}
        	<p>当for循环的对象为空时会执行</p>
    {% endfor %}
    

    自定义过滤器和标签

    django支持自定义过滤器和标签

    首先要做三步准备

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

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

    3. 在该py文件中,必须先写下面两句代码

      from django.template import Library
      register = Library
      
    # 自定义过滤器  跟默认的过滤器一样 最多只能接受两个参数
    @register.filter(name='baby')
    def index(a, b):
        return a + b
    
    # 自定义标签   可以接受任意多个参数
    @register.simple_tag(name='mytag')
    def mytag(a, b, c, d):
        return '%s?%s?%s?%s'%(a, b, c, d)
    
    # 自定义inclusion_tag
    """
    是一个函数 能够接受外界传入的参数 然后传递给一个html页面页面上获取数据 渲染 完成之后将渲染好的页面 放到调用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页面
    

    模板的继承

    你需要事先在你想要使用的页面上划定区域,之后在继承的时候你就可以使用你划定的区域

    {% block content %}
    {% endblock %}
    {#现在页面上利用block划定你以后可能想改的区域#}
    {#继承之后,就可以通过名字找到对应的区域进行修改#}
    {% extends 'home.html' %}
    
    {% block content %}
    	{#修改模板中的content区域内容#}
    {% endblock %}
    

    模板上的block区域越多,页面的扩展性越强

    建议你一个模板页面至少有三块区域

    css区域

    heml代码区域,可以设置多个block

    js区域

    有了这三块区域 就能够实现每一个页面都有自己独立的css和js代码

    模板的导入

    将html页面当做模块的直接导入使用

    {% include 'bform.html' %}
    
  • 相关阅读:
    js函数动态传参
    js 异步加载
    js 遍历
    安卓——implements——OnClickListener
    安卓——BroadcastReceiver
    关于Linux下的硬链接
    Linux 的文件类型
    linux 学习
    虚函数与重载函数的区别
    虚函数和友元
  • 原文地址:https://www.cnblogs.com/2222bai/p/11938827.html
Copyright © 2011-2022 走看看