一、视图层

(一)Request和Response对象

(1)Request对象

页面被请求时,Django创建的传给视图函数的Request对象

  1. method:返回请求方式,大写的字符串
  2. GET:返回GET请求所携带的数据,类字典对象
  3. POST:返回POST请求所携带的数据,类字典对象
  4. paht_info:返回用户访问的url,不包括域名
  5. body:请求体,byte类型,存放post请求携带的数据
# 以GET举例
request.GET.get(xxx='xxx')  # 默认获取最后一个元素
request.GET.getlist()  # 获取所有元素

(2)Response对象

视图函数必须有一个返回值,数据类型必须是HttpResponse(render和redirect都继承了HttpResponse)

  1. content:响应内容
  2. charset:响应内容的编码
  3. status_code:响应的状态码

(二)JsonResponse对象

(1)前后端分离

  1. HttpResponse对象的子类,专门用来生成JSON编码的响应,用于前后端数据交互

  2. 后端只需要写好相应的url接口,前端访问接口,只需要返回一个大字典+开发文档(告诉前端,接口会返回哪些数据)即可

from django.http import JsonResponse
import json
def index(request):
    user_dic = {'name':'json是个傻逼','password':123}

    l = [1,2,3,3,4,5,65]
    return JsonResponse(l,safe=False)

(2)json_dumps_params参数

默认转码成ascii值,设置该参数中的ensure_ascii来控制不对中文进行转码

# 如何让json不对中文进行转码 方法1
json_str = json.dumps(user_dic,ensure_ascii=False)
return HttpResponse(json_str)

#如何让json不对中文进行转码 方法2
return JsonResponse(user_dic,json_dumps_params={"ensure_ascii":False})

(3)safe参数

JsonReponse默认序列化字典,如果序列化其他类型(json模块可以序列化的),你需要设置safe参数为False

l = [1,2,3,3,4,5,65]
return JsonResponse(l,safe=False)

(三)FBV与CBV

  1. FBV:基于函数的视图

    # views.py
    from django.shortcuts import render,HttpResponse,redirect
    
    def get(self,request):
    print('mylogin>get')
    return  render(request,'login.html')
    
    # urls.py
    url(r'^get/', views.get), 
  2. CBV:基于类的视图

    # views.py
    from django.shortcuts import render,HttpResponse,redirect
    from django.views import View
    
    class MyLogin(View):
        def get(self,request):
            print('mylogin>get')
            return  render(request,'login.html')
    
        def post(self,request):
            print('mylogin>post')
            return HttpResponse('post')
    
    # urls.py
    url(r'^login/', views.MyLogin.as_view()), 

(四)CBV的源码

  1. 项目一启动就会自动执行as_view方法,返回调用函数view(本质上也是FBV)

  2. 函数view中返回调用对象的dispatch方法

    @classonlymethod
    def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):  # 闭包函数
            self = cls(**initkwargs)  # cls是我们自己写的类 MyLogin  self是我们自己定义的类的对象
            # 在看源码的时候 你一定要把握住一个顺序 对象在查找属性和方法的时候
            return self.dispatch(request, *args, **kwargs)
        return view
  3. dispatch函数中利用反射方法获得请求的方式,从而调用对应方法

    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        # 判断当前请求方式在不在默认的八个方法内
        # 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方法

(五)装饰器

(1)FBV加装饰器

和普通函数加装饰器一样

(2)CBV加装饰器

可以利用method_decorator装饰器将函数装饰器转化为方法装饰器

  1. 函数装饰器直接加
  2. 方法装饰器直接加(推荐用法)
  3. 方法装饰器通过name指定
  4. 通过自定义dispatch方法,给所有方法加
from django.views import View
from django.utils.decorators import method_decorator
from django.utils.safestring import mark_safe
# 3.方法装饰器通过name指定
@method_decorator(outer,name='post')
# 4.1 方法装饰器通过name指定dispatch给所有方法加
# @method_decorator(outer,name='dispatch')
class MyLogin(View):
    # 4.2 通过自定义dispatch方法,给所有方法加
    def dispatch(self, request, *args, **kwargs):  # 在视图函数执行之前的操作
        return super().dispatch(request,*args,**kwargs)

    # 1. 函数装饰器直接加
    @outer
    def get(self,request):
        print('mylogin>get')
        return  render(request,'login.html')

    # 2. 方法装饰器直接加 (推荐写法)
    @method_decorator(outer)
    def post(self,request):
        print('mylogin>post')
        return HttpResponse('post')

二、模板层

(一)模板语法

  1. {{}}:和变量相关
  2. {%%}:和逻辑相关

(二)模板传值

(1)传值方式(render)

  1. 通过字典传值:适用于传值较少
  2. 通过locals()传值:将当前所在名称空间所有的名字全部传递给html页面,适用于传值较多
# 给html传值的方式1,传递的值较多时,不方便
return render(request,'test.html',{'n':n})

# 给html传值的方式2,local()会将当前所在名称空间所有的名字全部传递给html页面
return render(request,'test.html',locals())

(2)基础数据类型

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

(3)函数和对象

  1. 给html页面传递函数名或类名的时候,模板语法会自动加括号调用,并返回返回值
  2. 模板语法不支持函数传参,即传给html的函数只能是无参函数或者不需要传参调用的函数

(4)点(.)

  1. Django中的模板语言的.具有特殊含义,可以用于字典取值,属性或方法调用,数字索引查询
  2. 查询顺序:字典查询>属性或方法查询>数字索引查询
# views.py
dic = {'username':'wick','hobby':['read','study',['run','sing',{'age':18}]]}

# html中取值方法
{{dic.hobby.2.2.age}}  # 18

(三)过滤器|

(1)定义和语法

  1. 模板语法提供的的内含方法,可以快速的处理数据
  2. 语法:{{ value|filter_name:参数 }}
  3. 支持链式操作
  4. 管道符|左右没有空格

(2)常用过滤器

  1. length:返回值的长度
  2. filesizeformat:返回自动转换后的文件大小
  3. safe:返回转义后html和JS标签(默认不会自动转移html标签)
  4. add:返回数字相加结果,支持字符串
  5. slice:返回切片结果,支持步长,负数
  6. default:值为空返回默认值,否则返回值本身
  7. truncatechar:截取文本字符,包含···
  8. truncatewords:截取文本内容,不包含···,根据空格判断
<p>统计长度:{{ s|length }} (无法统计,默认返回0)</p>
<p>文件大小自动转换:{{ file_size|filesizeformat }}</p>
<p>展示带有标签的文本:{{ sss }}(默认不会自动转换成html标签,防止恶意攻击)</p>
<p>展示带有标签的文本:{{ sss|safe }}(safe设置自动转换成html标签)</p>
<p>加法运算:{{ n|add:234567 }} (内部异常捕获,支持数字相加,字符串相加,都不符合,返回'')</p>
<p>切片操作:{{ l|slice:'0:2'}} (支持步长、负数)</p>
<p>判断是否有值:{{ is_value|default:'is_value变量名指向的值为空' }}</p>
<p>截取文本内容(字符):{{ s|truncatechars:4}} (截取4个字符,包含···)</p>
<p>截取文本内容:{{ s2 | truncatewords:5}} (按照空格截取5个单词,不包含···)</p>

(3)前后端取消转义

  1. 前端:safe

  2. 后端:mark_safe

    from django.utils.safestring import mark_safe
    res = mark_safe(cc)

(四)标签

逻辑相关

(1)for循环

  • 分类

    1. 普通for循环
    2. for ... empty:当for循环的对象为空时,执行该语句
  • 自带参数forloop
    1. forloop.counter0:当前循环的索引值(从0开始)
    2. forloop.counter:当前循环的计数(从1开始)
    3. forloop.revcounter0: 当前循环的倒序索引值(从0开始)
    4. forloop.revcounter: 当前循环的倒序计数值(从1开始)
    5. forloop.first: 判断当前循环是不是第一次循环(布尔值)
    6. forloop.last :判断当前循环是不是最后一次循环(布尔值)
    7. forloop.parentloop : 本层循环的外层循环

(2)if判断

if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断

{% for foo in l %}
    {% if forloop.first %}
        <p>这是第一个数</p>
    {% elif forloop.last %}
        <p>这是最后一个数</p>
    {% else %}
        <p>中间的数{{ foo }}</p>
    {% endif %}
    {% empty %}
        <p>当for循环的对象为空时,执行该语句</p>
{% endfor %}

(3)with

  1. 定义一个中间变量,多用于给一个复杂的变量起别名,等号左右不要加空格。
  2. 别名只可以在with内部可以用
<!--dic = {'username':'wick','hobby':['read','study',['run','sing',{'age':18}]]}-->
{% with  dic.hobby.2.2.age as age   %}
    <p>{{ age }}</p>
{% endwith %}

(4)csef_token

  1. 这个标签用于跨站请求伪造保护。

  2. 在页面的form表单里面写上{% csrf_token %}

(五)自定义

自定义必须要做的三件事:

  1. 在应用下新建一个templatetags的文件夹
  2. 该文件夹内新建一个任意名称的py文件
  3. 在该py文件中必须先写下面两句话:
    1. from django.template import Library
    2. register = Library()

可以自定义过滤器、标签和inclusion_tag,使用时必须在页面上加载一下

  • inclusion_tag:是一个函数,能够接受外界传入的参数,然后传递给一个html页面,页面获取数据渲染完成后将页面返回
# mytag.py
# 自定义过滤器(和默认的过滤器一样,最大只能接受两个参数)
@register.filter(name='baby')
def index(a,b):
    return a+b

# 自定义标签,可以接受任意多个参数
@register.simple_tag(name='mytag')
def mytag(a,b,c,d):
    return f'{a}?{b}?{c}?{d}'

# 自定义inclusion_tag
@register.inclusion_tag('mytag.html',name='xxx')
def index6(n):
    l = []
    for i in range(n):
        l.append(f'第{i}项')
    return locals()  # 将l直接传递给mytag.html页面
<p>自定义过滤器的使用</p>
{% load mytag %}
{{ 1|baby:1 }}

{#<p>自定义标签的使用,可以接受多个参数,参数必须用空格隔开</p>#}
{#{% load mytag %}#}
{#{% mytag 'a' 'b' 'c' 'd' %}#}

{#<p>自定义的过滤器可以在逻辑语句中使用,而自定义标签不可以</p>#}
{#{% if 1|baby:2 %}#}
{#    <p>有值</p>#}
{#{% else %}#}
{#    <p>无值</p>#}
{##}
{#{% endif %}#}

<p>自定义inclusion_tag的使用,当需要使用一些页面组件,且该组件需要参数才能正常渲染时使用</p>
{% load mytag %}
{% xxx 11 %}
</body>
</html>

(六)模板的继承和导入

(1)继承模板extends

在子页面中在页面最上方使用下面的语法来继承母板

{% extends 'home.html' %}

(2)块(block)

在父页面上利用block划定想要修改的区域,继承后就可以通过名字找到对应的名字找到该区域,并修改

  1. 模板上的block区域越多,页面的扩展性越强,推荐你一个模板页面至少有三块区域(css区域,html代码区域,js区域)
  2. 通过这三个区域,就能够实现每一个页面都有自己独立的css和js代码
  3. 可以在子页面上通过{{ block.super }}沿用父页面的内容

(3)导入(include)

将html页面当做模块的直接导入使用:{% include 'form.html'%}

{% block content %}
    <p>我改成home1页面内容</p>
    {{block.super}}
    {% include 'form.html' %}
{% endblock %}

{% block css %}
    <style>
        p {
            color: green;
        }
    </style>
{% endblock %}

{% block js %}
    <script>
        alert('login')
    </script>
{% endblock %}

(day52)四、视图层、模板层的更多相关文章

  1. day 45 Django 的初识2 路由层,视图层,模板层

    前情提要: 今天继续学习Django 的内容, 今天主要和渲染相关 1>配置路由 >2:写函数 >3 指向url 一:路由层 1:配置静态支持文件 1:路由层的简单配置 >dj ...

  2. DjangoMTV模型之视图层views及模板层template

    Django视图层中views的内容 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容(render),也可以是一个重定向( ...

  3. python 全栈开发,Day69(Django的视图层,Django的模板层)

    昨日内容回顾 相关命令: 1 创建项目 django-admin startproject 项目名称 2 创建应用 python manage.py startapp app名称 3 启动项目 pyt ...

  4. Django的路由层和视图层

    一丶Django 的路由层(URLconf) URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django ...

  5. Web框架之Django_03 路由层了解(路有层 无名分组、有名分组、反向解析、路由分发 视图层 JsonResponse,FBV、CBV、文件上传)

    摘要: 路由层 无名分组 有名分组 反向解析 路由分发 名称空间 伪静态网页.虚拟环境 视图层 JsonResponse FBV 与 CBV(function base views与class bas ...

  6. Django 路由层与视图层

    1.路由层 1.1无名分组 1.2 有名分组 1.3 反向解析 1.4 路由分发 1.5 名称空间 2.伪静态网页 3.虚拟环境 4.视图层 1.1 JsonResponse 1.2 FBV与CBV ...

  7. 052.Python前端Django框架路由层和视图层

    一.路由层(URLconf) 1.1 路由层简单配置 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Dj ...

  8. $Django 虚拟环境,2.0、1.0路由层区别,Httprequest对象,视图层(fbv,cbv),文件上传

    1 虚拟环境:解决问题同一台机器上可以运行不同版本的django,  1 用pychanrm创建--->files-->newproject--->选择虚拟环境  2 setting ...

  9. Django框架(四) Django之视图层

    视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . ...

随机推荐

  1. 使用scale等比例缩放图片

    功能需求: 在下拉框中选择你所需要缩放的比例, 选择好了之后,图片会按照你选择的比例进行缩放 1==>如何获取select中option选中的值 在select添加事件change 和双向绑定v ...

  2. Less(2)

    1.先判断注入类型 (1)首先看到要求,要求传一个ID参数,并且要求是数字型的:?id=1 (2)输入?id=1' and 1=1 出现错误 (3)输入 ?id=1 and 1=1 页面显示正常 (4 ...

  3. 数据嵌入js的关系图

    参照echarts官网,改了一下效果图: 数据放在了js里. 代码: <%@ page language="java" contentType="text/html ...

  4. IT人的立功,立言,立德三不朽

    最近几个月很忙,忙着当奶爸,忙着做加班狗,忙着补裤裆学技术……以至于快忘了要思考人生了! 古人立志穷极一生追求“立德”,“立功”,“立言”,以求不朽,为万世所景仰,为后人所传颂,实现人生的意义.立德者 ...

  5. C语言中,字符型数字与常数型数字的加减实现

    char in-str[10],out-str[10]; for(int i=0;i<10;i++) { out-str[i]=9-(in-str[i]-'0')+'0'; }

  6. 【LOJ6620】「THUPC 2019」不等式 / inequality(线段树)

    点此看题面 大致题意: 给你两个长度为\(n\)的数组\(a_i\)和\(b_i\),定义\(f_k(x)=\sum_{i=1}^k|a_ix+b_i|\),对于\(k=1\sim n\)的每个\(f ...

  7. umi+dva+antd新建项目(亲测可用)

    首先全局安装dva+umiumi:npm install -g umidva:npm install -g dva-cli 通过脚手架创建项目 一: mkdir myapp && cd ...

  8. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 6

    18.5.3  PDO的错误处理模式 PDO共提供了3种不同的错误处理模式,不仅可以满足不同风格的编程,也可以调整扩展处理错误的方式. 1.PDO::ERRMODE_SILENT 这是默认模式,在错误 ...

  9. Chapter 2 :重构的原则

    1,什么是重构? 在不改变软件可观察行为的前提下,使用一些重构的手法,提高代码可读性. 换句话说,在保持软件可用的前提下,修改代码使得更加容易被理解. 2,为什么重构? 为了后续的代码维护和修改,易读 ...

  10. DevExpress 使用 GridControl 时,数据源无法立即更新的问题

    背景 在使用 DevExpress 的 GridControl 为其实现 Checkbox 列,发现如果勾选了三行的数据,在遍历 GridControl 绑定的数据源时 Checkbox 列的数据仅有 ...