一,类视图

  1,类视图介绍

  视图是一个可调用的对象,它接收一个请求然后返回一个响应,这个可调用对象可以不只是函数,Django还提供一些可以用作视图的类,叫做类视图。

以函数的形式进行定义的视图就是函数视图,视图函数便于理解,但是遇到一个视图函数对应的路径提供了多种不同的HTTP请求方式的支持时(get,post,delete,put),需要在一个函数中写不同的业务逻辑,代码的可读性和复用性就很低, 所以引入类视图进行解决。

  2,使用类视图

  ①创建一个新的应用进行使用
python manage.py startapp app02
  ②创建路由

Web开发基础之Django二_django

 

 

from django.conf.urls import url
from app02.views import *
urlpatterns = [
    url(r'^test', TestView.as_view()),
]

  

  ③ 在主路由引入

Web开发基础之Django二_html_02

 

   ④定义类视图

Web开发基础之Django二_自定义_03

 

   定义类视图需要导入视图类 View

from django.shortcuts import render, HttpResponse
# 导入视图类
from django.views.generic import View
# Create your views here.

class TestView(View):
    def get(self, request):
        return HttpResponse('这是GET请求')
    def post(self, request):
        return HttpResponse('这是POST请求')

  测试 

d:\web\devops\mydjango>curl -X POST http://127.0.0.1:8000/app02/test
杩欐槸POST璇锋眰
d:\web\devops\mydjango>curl  http://127.0.0.1:8000/app02/test
杩欐槸GET璇锋眰

  加参数-X POST为post请求 

  不加参数默认为get请求

  在windows的cmd请求返回为乱码

  使用Postman测试

Web开发基础之Django二_html_04

 

 Web开发基础之Django二_定义类_05

 

   3,使用类视图实现简单登录

  ①定义路由

Web开发基础之Django二_django_06

 

 

 url(r'^login', LoginView.as_view(), name='log'),

  ②定义类视图

Web开发基础之Django二_高亮_07

 

   ③创建app02的templates文件夹

  把登录的页面login.html放入

Web开发基础之Django二_自定义_08

 

   默认会访问 根目录下的templates的登录页面

Web开发基础之Django二_高亮_09

 

   在setting把创建的应用加入

  否则无法访问 会出现下面提示

Web开发基础之Django二_django_10

 

 

Web开发基础之Django二_定义类_11

 

   页面访问

http://127.0.0.1:8000/app02/login

Web开发基础之Django二_html_12

 

   补充:模板分应用配置

  ①把对应应用设置在setting

Web开发基础之Django二_自定义_13

 

   ②在应用下新建templates并且在该文件夹下面再创建一个文件夹

  然后把页面放入到该文件夹

Web开发基础之Django二_定义类_14

 

   ③修改视图文件

Web开发基础之Django二_html_15

 

   这样配置即使两个templates出现了相同文件名也会找到对应的页面

  解释

  查看配置文件setting可以找到BASE_DIR为

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

  其中__file__代表文件本身,例如本次运行的login.html 如果找的的是跟目录下的login.html即

  __file__ == D:\web\devops\mydjango\templates\login.html

  os.path.abspath(__file__) 为文件绝对路径即 D:\web\devops\mydjango\templates\login.html

  os.path.dirname(os.path.abspath(__file__)) 为改文件所在的文件夹即D:\web\devops\mydjango\templates\

  os.path.dirname(os.path.dirname(os.path.abspath(__file__)))则为文件夹的文件夹即 D:\web\devops\mydjango\

  同理如果找的是应用app02下对应的页面login.html则BASE_DIR为  D:\web\devops\mydjango\app02再通过setting的拼接templates

Web开发基础之Django二_html_16

 

   所以此时运行的跟目录为 D:\web\devops\mydjango\app02\templates

Web开发基础之Django二_django_17

 

   如果在视图设置如下即可找到正确login.html

  即使对应的页面名称有冲突也不会影响找到正确的页面

Web开发基础之Django二_定义类_18

 

   二,模板语法

  1,变量的使用

  在模板中,如果想要输出后端传输的变量。需要使用到模板的标签语法。

语法: {{变量名称}}

  示例:在后端传入变量到模板中,在模板中调用输出变量。

  ①定义路由

Web开发基础之Django二_自定义_19

 

   ②定义视图

Web开发基础之Django二_html_20

 

   ③在模板中调用输出变量

Web开发基础之Django二_html_21

 

   页面显示

Web开发基础之Django二_高亮_22

 

   本次变量在视图类已经设置好了 也可以通过web页面传递,修改视图

class TemplateView(View):
    def get(self, request):
        return render(request, 'app02/tpl.html', {'name': request.GET.get('name')})

  

  页面传递name值

http://127.0.0.1:8000/app02/tpltest?name=linux

Web开发基础之Django二_定义类_23

 

   2,传递多个变量

  当在视图需要往模板传输很多变量时,如果一个一个写,会很繁琐不方便,在框架中提供了,locals方法,可以传递所有变量。

在上面列子视图中,继续进行操作

  ①使用locals方法

Web开发基础之Django二_高亮_24

 

 

class TemplateView(View):
    def get(self, request):
        username = 'devops'
        dateTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        age = 18
        return render(request, 'app02/tpl.html', locals())

    ②在模板中调用输出变量值

Web开发基础之Django二_定义类_25

 

 

<body>
    {{ username }}
    当前时间为:{{ dateTime }}
    <p>年龄:{{ age }}</p>
</body>

  页面显示

Web开发基础之Django二_自定义_26

 

   list和dict值获取

  ①插入列表和字典数据

Web开发基础之Django二_自定义_27

 

   ②在模板中调用输出变量

Web开发基础之Django二_django_28

 

   页面输出 

Web开发基础之Django二_定义类_29

 

   获取list或者dict中的其中一个值,可以通过.进行获取。list填写数字下标,dict填写key。

Web开发基础之Django二_自定义_30

 

   页面显示

Web开发基础之Django二_html_31

 

   3,过滤器

  对于通过视图输出到模板中的数据,进行二次的处理。可以通过模板过滤器实现。

语法格式:{{ obj | filter: param }}

  常用过滤器

过滤器

作用

实例

add

给变量加上对应的值

{{ age | add:100}} 

capfirst

首字母大写

 

 {{ username | capfirst }}

cut

从字符串中移除指定的字符

{{ username | cut:'d' }} 

date

格式化日期字符串

{{ day_time | date:'Y-m-d H:i:s' }} 

default

如果值是False,就替换成设置的默认值,否则就用本来的值

 
{{ hobby | default:'这是一个空列表' }}
{{ list1 | default:'这是一个空列表' }}

    

  3,模板控制器

  1,判断语句  

  语法

语法结构:{% if %}...{% endif %} 或{% if %}…{%else%}…{% endif %}:

  标签判断一个变量值,如果是ture,即为存在,不为空并且不是false的boolean值,系统则会显示{% if %}和{% endif %}中间的所有内容。

  示例

Web开发基础之Django二_html_32

 

 

{% if age >= 18 %}
你已成年
{% else %}
你未成年
{% endif %}

  注意:通过请求接收到的数字,其实是一个字符串类型

  2,循环语句for

  语法

语法结构:{%for%}...{%endfor%}

  {% for %}标签允许你按顺序遍历一个序列中的各个元素,每次循环模板系统都会渲染{% for %}...{% endfor %}之间的所有内容。

  2.1遍历列表

  模板标签写法

    <!--    for语句   -->
    <!--    遍历列表    -->
    <ul>
        {% for one in hobby  %}
            <li>{{ one }}</li>
        {% endfor%}
    </ul>
    <!-- 倒序 -->
    <ul>
        {% for one in hobby reversed %}
            <li>{{ one }}</li>
        {% endfor%}
    </ul>

    <!--    计数器 -->
    <ul>
        {% for one in hobby  %}
            <li>{{ forloop.counter }},{{ one }}</li>
        {% endfor%}
    </ul>

    <ul>
        {% for one in hobby %}
            <!--   判断是否第一个元素    -->
            {% if forloop.first %}
                <li style="color:red">{{ forloop.counter }},{{ one }}</li>
            <!--  判断是否最后一个元素    -->
            {% elif forloop.last %}
                <li style="color:green">{{ forloop.counter }},{{ one }}</li>
            {% else %}
                <li>{{ forloop.counter }},{{ one }}</li>
            {% endif %}
        {% endfor%}
    </ul>
    <!--    遍历字典-->
    <ul>
        {% for key,value in introduce.items %}
            <li>{{ key }}:{{ value }}</li>
        {% endfor %}
    </ul>
</body>

  页面显示

Web开发基础之Django二_定义类_33

 

   四,自定义过滤器

  在上面列子中,学习使用了模板中提供的基本过滤器,但是有时候还是不能够满足业务需求。这时,可以选择使用自定义过滤器

  自定义过滤器实现的步骤:

  ①在应用中创建templatetags

  ②在其中创建任意.py结尾文件

  ③导入 from django import template 方法

  ④注册方法 register = template.Library()

  ⑤通过装饰器的写法 自定义过滤器

  示例:实现一个自定义过滤器

  ①创建模板templatetags

  即在对应应用下新建一个文件夹 本次是在应用app02下创建

Web开发基础之Django二_html_34

 

   ②在该文件夹创建一个以py结尾的文件

Web开发基础之Django二_定义类_35

 

 

   ③导入方法

Web开发基础之Django二_自定义_36

 

 

   ④注册方法

Web开发基础之Django二_定义类_37

 

 

   ⑤单个参数(使用装饰器register.filter)

from django import template
register = template.Library()

# 单参数过滤器
@register.filter
def filter_add(v1, v2):
return v1 + v2

  模板调用

Web开发基础之Django二_高亮_38

 

 

  <ul>
        <!--    加载模板    -->
        {% load my_tags %}
        <!--    调用  -->
        {{ age | filter_add:2}}
    </ul>

  页面显示

  age原始值为17 加上2值为19

Web开发基础之Django二_django_39

 

 

  如遇到以下问题 

Web开发基础之Django二_自定义_40

 

 Web开发基础之Django二_django_41

 

   ⑥多参数(使用装饰器register.simple_tag)

Web开发基础之Django二_高亮_42

 

 

@register.simple_tag
def filter_add2(v1, v2, v3, v4):
    return v1 + v2 + v3 + v4

  模板调用

Web开发基础之Django二_高亮_43

 

   页面显示

Web开发基础之Django二_html_44

 

   五,模板继承

  在实际业务开发中,进行会使用页面中相同的部分,为了能够使页面模板部分可以复用。可以采用模板继承的方式。

  1,传统模板加载

  以主机列表为例

  ①定义url

Web开发基础之Django二_html_45

 

   ②静态资源部署

Web开发基础之Django二_html_46

 

   ③静态模板引入

  由主机列表模板复制过来

Web开发基础之Django二_定义类_47

 

  注意:需要提前在setting.py中设置好模板路径和静态资源路径

  ④定义类视图

Web开发基础之Django二_django_48

 

   ⑤修改引入静态资源的路径

  例如css js对应的路径

  查看页面加载效果

Web开发基础之Django二_高亮_49

 

   

  按照以上方式,继续快速创建一个用户管理的页面

  

  使用传统模板加载方式的问题:

  ①公共部分

Web开发基础之Django二_html_50

 

   ②修改公共部分之后还需要修改多个页面

  再按照以上方法创建一个用户的页面

Web开发基础之Django二_django_51

 

   2,模板继承方式

  ①编写基本页面

  基本页面是复制host.html页面

  找到每个页面的独立页面对应代码删除掉 本次对应的是main代码

Web开发基础之Django二_自定义_52

 

   写入代替代码 body为自定义名称

Web开发基础之Django二_html_53

 

   ②继承模板

  修改hots.html 把除了刚刚base.html内删除的main代码以外的代码删除只保留main代码

Web开发基础之Django二_定义类_54

 

 Web开发基础之Django二_定义类_55

 

   删除代码后未继承时页面显示

Web开发基础之Django二_定义类_56

 

   模板继承

Web开发基础之Django二_定义类_57

 

   同理设置用户列表的继承

Web开发基础之Django二_定义类_58

 

   修改base.html模板把对应链接修改一下

Web开发基础之Django二_html_59

 

   页面显示

Web开发基础之Django二_定义类_60

 

 Web开发基础之Django二_定义类_61

 

   补充:点击标签高亮

  以上示例点击主机列表和用户列表时不会对应高亮 如果在样式设置了高亮<li class="active">则会一直高亮

  在基础模板base.html的<body></body>内增加以下代码

  <script>
            // 1,获取当前Url
            var currentUrl = window.location.pathname
            // 2,遍历查看li标签下面的a对应的href 进行url匹配
            $('.nav > li > a').each(function(index,item){
                $(this).parent().removeClass('active')
            // 3,获取href
            // console.log($(this).attr('href'))
                if($(this).attr('href') == currentUrl) {

                $(this).parent().addClass('active')
                }
            })
        </script>

  代码解析

#获取当前页面的Url
window.location.pathname

  如下图所示

Web开发基础之Django二_高亮_62

 

   遍历nav -> li -> a标签 首先取消所有页面的高亮,如果url于当前点击的url一致 则单独高亮对应的标签

  页面显示

Web开发基础之Django二_自定义_63

 

 Web开发基础之Django二_html_64