• Django之URL&Views&Template


    1. Django的使用

    1.1 MVC和MTV框架

    1)MVC

    • M:模型,负责业务对象和数据库的映射(ORM)
    • V:视图,负责与用户的交互(页面)
    • C:控制器,负责与用户的交互(页面)

    2)MTV

    • M:模型(Model),负责业务对象和数据库的关系映射(ORM)
    • T:模板(Template),负责如何把页面展示给用户(html)
    • V:视图(View),负责业务逻辑,并在适当时候调用Model和Template

     此外还需一个URL分发器,将一个个URL请求分发给不同的View处理。

    1.2. Django的安装和使用

    1)Django的安装

    • 直接通过pip3 install去下载对应版本的Django即可

    2)创建django project

    • 先新建一个Django_projects文件夹,进入这个文件夹后,创建第一个项目。
    django-admin startproject mysite   # 创建了一个名为"mysite"的Django 项目
    • django project的目录结构:
    mysite
    |--- manage.py        # Django项目里的工具,可以通过它调用django shell和数据库,启动关闭项目与项目交互等
    |--- mysite              
    |--- __init__.py |--- settings.py # 包含了项目的默认设置 |--- urls.py # 负责把URL模式映射到应用程序 |--- wsgi.py
    • 注意:
      • 创建Django项目不能用中文
      • 要将django-admin.exe的路径配置到环境变量中(这个文件的位置一般在python解释器目录的Scripts目录下)

    3)启动Django

    python manage.py runserver 127.0.0.1:8080  # 此时已经可以启动django项目了,只不过什么逻辑也没有

    4)创建应用

    • 通过manage.py可以创建应用
    python manage.py startapp app01   
    # 通过执行manage.py文件来创建应用,
    # 应该在这个manage.py的文件所在目录下执行这句话,因为其他目录里面没有这个文件


    python manage.py startapp app02 # 每个应用都有自己的目录,每个应用的目录下都有自己的views.py视图函数和models.py数据库操作相关的文件

    5)修改settings配置

    • 将URL中的路径和本地文件系统上的路径做对应关系映射
    STATIC_URL = '/static/'               # 这里表示的是URL中的路径
    STATICFILES_DIRS=( 
       os.path.join(BASE_DIR,"static"),  # 这里表示的是本地文件系统的路径
    )
    • 将csrf中间件选项暂时注释
    # 'django.middleware.csrf.CsrfViewMiddleware',   #这里先注释掉

    6)启动项目

    python manage.py runserver 127.0.0.1:8080  # 本机可以不写ip地址了 默认是本机的8000端口

    2. URL路由系统

    2.1 基本使用格式

     django2.0之后是使用了path,但是也向下兼容使用url,导入url即可。

    from django.conf.urls import url
    urlpatterns = [
         url(正则表达式, views视图函数,参数,别名),
    ]
    # 正则表达式:一个正则表达式字符串
    # views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
    # 参数:可选的要传递给视图函数的默认参数(字典形式)
    # 别名:一个可选的name参数

    2.2 URL分组

    1)无名分组

    所谓无名分组,其实就是给视图函数传递位置参数。

    将要传递的参数在放入小括号()中,然后在对应的视图函数中按顺序接收对应的参数即可。

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    urlpatterns = [# 无名分组 (给应用视图函数传递位置参数)
        url(r'books/(d{4})/$', views.year),  # 完全匹配
        url(r'^books/(d{4})/(d{2})/$', views.year_mouth),
        url(r'^books/(d{4})/(d{2})/(d{2})/$', views.year_mouth_day),
    ]
    • urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续
    • 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)
    • 不需要添加一个前导的反斜杠(也就是写在正则最前面的那个/),因为每个URL 都有
      • 例如,应该是^books而不是 ^/books
    • 每个正则表达式前面的 'r' 是可选的但是建议加上
    • ^books&  以什么结尾,以什么开头,严格限制路径
    • # 是否开启URL访问地址后面没有/跳转至带有/的路径的配置项,默认是开启的
      APPEND_SLASH=True

    2)有名分组

    所谓有名分组,就是捕获URL中的值并以关键字参数形式传递给视图函数。

    分组命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。

    urlpatterns = [
        url(r'^articles/(?P<year>[0-9]{4})/$', views.year),
    # 某年的,(?P<year>[0-9]{4})这是命名参数,那么函数year(request,year),形参名称必须是year这个名字
    # 如果这个正则后面没有写$符号,即便是输入了月份路径,也会被它拦截下拉,因为它的正则也能匹配上
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.details), ]
    • 也可以对应views函数的默认值参数,也就是说视图函数中可以指定参数的默认值
    • 捕获的参数永远都是字符串

    2.3 URL分发

    因为一个项目中可能有多个应用,所以我们需要对URL做分发。

    要将新创建的应用添加到setttings配置文件中的 INSTALLED_APPS 中

    使用include即可完成对URL的分发:(include需要手动导入)

    from django.conf.urls import url,include
    urlpatterns = [
         # 输入不同的url找到不同的app 分发给不同的应用的urls.py
        url(r'^app01/', include('app01.urls')), 
         # 这时app01中的urls只需要处理app01后面的那部分url了
        url(r'^app02/', include('app02.urls')),
    
    ]

    2.4 URL别名

    通过给URL定义一个别名来防止URL路径更改后URL失效。

    1)使用别名

    # 给url匹配模式起名为 home,别名不需要改,路径就可以随便改了,别的地方要使用这个路径,则用这个别名即可
    url(r'^home', views.home, name='home'),  
    url(r'^index/(d*)', views.index, name='index'), 

    2)在模板中的引用

    {% url 'home' %}  #模板渲染的时候,被django解析成了这个名字对应的那个url,这个过程叫做反向解析 

    3. Views视图函数

    http请求中产生的核心对象:(所在位置:django.http)

    • http请求:HttpRequest对象
    • http响应:HttpResponse对象

    3.1 HttpRequest对象

    1) path

    • 请求页面的全路径,不包括域名,也不包括参数

    2) method

    • 请求中使用的HTTP方法的字符串表示,全大写表示
    if request.method=="GET":
        do_something()
    elif request.method=="POST":
        do_something_else()

    3) GET

    • 包含所有HTTP GET参数的类字典对象

    4) POST

    • 包含所有HTTP POST参数的类字典对象
    • 服务器收到空的POST请求的情况有可能发生,也就是说,表单form通过HTTP POST方法提交请求,但是表单中可能没有数据
      • 因此不能使用if req.POST来判断是否使用了HTTP POST 方法;应该使用 if req.method=="POST"

    5) session

    • 唯一可读写的属性,代表当前会话的字典对象
    • 自己有激活Django中的session支持时该属性才可用

    6) COOKIES

    • 包含所有cookies的标准Python字典对象
    • keys和values都是字符串

    7) FILES

    • 包含所有上传文件的类字典对象
    • FILES中的每一个Key都是<input type="file" name="" />标签中 name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
      • filename: 上传文件名,用字符串表示
      • content_type: 上传文件的Content Type
      • content: 上传文件的原始内容

    8) user

    • 是一个django.contrib.auth.models.User对象,代表当前登陆的用户
    • 如果访问用户当前没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例
    • 可以通过user的is_authenticated()方法来辨别用户是否登陆:if req.user.is_authenticated()
    • 只有激活Django中的AuthenticationMiddleware时该属性才可用

    方法:

    • get_full_path()
      • 得到包含参数的path
    • request.POST.getlist("")

    3.2 HttpResponse对象

    HttpResponse对象由我们自己创建,且每个view请求处理方法必须返回一个HttpResponse对象。

    HttpResponse类在django.http.HttpResponse,需要手动导入。

    1)HttpResponse对象上扩展的常用方法

    • 页面渲染:
      • render()     
      • render_to_response()
    • 页面跳转:
      • redirect("路径")
    • 直接返回:
      • HttpResponse("xxoo")
    • locals()函数可以直接将函数中所有的变量传给模板
      return render(req,"my backend.html",locals()) 

    2)render和redirect的区别

    • render的页面需要模板语言渲染,且url并没有变化,还是保持不变
    • redirect是直接跳转,url会改变

    4. Template模板系统

    模板渲染的两种特殊符号:

    • 变量相关的用  {{ }}
    • 逻辑相关的用  {% %} 

    4.1 变量的使用语法

    1)基本使用

    使用双大括号来引用变量:

    {{ var_name }}

    Views函数中的代码:

    def current_time(req):
        now=datetime.datetime.now()
        return render(req, 'current_datetime.html', {'current_date':now}) 
        # 在模板中,就可以使用{{current_date}}来引用这里的变量

    2)深度变量的查找

    • 利用点号来查找深度变量
    • 点号可以访问列表索引,也可以通过字典的键来访问对应的值,同样也可以访问对象的属性以及方法
    {{ items.2 }}      # 通过列表的索引来获取对应的值
    {{ person.name }}  # 通过字典的key来获取对应的值
    {{ date.month }}   # 通过点号来访问对象的属性
    {{ var.upper }}    # 通过访问对应的方法来调用它

    4.2 变量的过滤器(filter)

    1)语法格式

    • {{ obj|filter:param }}

    2)常用的过滤器

    # default:如果值是False,就替换成设置的默认值,否则就是用本来的值
    {{ value|default:'值是False'}}
    # length:返回值的长度,作用于字符串和列表 {{ name_list|length }}
    # slice:切片,支持python中可用的所有数据类型 {{ name_list|slice:'1:3' }} {{ s|slice:'1::2' }} # add:给变量加上相应的值 {{ value|add:3 }} # capfirst:首字母大写 {{ value|capfirst }} # upper:字符转换成大写 {{ value|upper }} # cut:从字符串中移除指定的字符 {{ value|cut:' '}} # date:格式化日期字符串 {{ value|date:'Y-m-d' }}    # join:设定连接符将可迭代对象的元素连接在一起,与字符串的join方法相同 {{ name_list|join:'_'}} {{ tu|join:'+'}} # safe:告知Django这段代码为安全的,不必进行转义 {{ value|safe}}

    4.3 标签(tag)的使用

    • 使用标签的格式:  {% tags %}

    1){% if %}

    • {% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量
    • {% if %} 标签不允许同一标签里同时出现and和or
    • {% if %} 可以和过滤功能进行配合
    {% if num >= 100 and 8 %}
        {% if num > 200 %}
            <p>num大于200</p>
        {% else %}
            <p>num大于100小于200</p>
        {% endif %}
    {% elif num < 100%}
        <p>num小于100</p>
    {% else %}
        <p>num等于100</p>
    {% endif %}

    2){% for %}

    <ul>
    {% for obj in list %}
        <li>{{ obj.name }}</li>
    {% endfor %}
    </ul>
    
    # 在标签里可以用reversed来反序循环列表
    {% for obj in list reversed %}
        ...
    {% endfor %}
    • forloop.first  第一次循环
    • forloop.last  最后一次循环
    • 示例:
      {% for foo in name_list %}
          {% if forloop.first %}
              {{ foo }}
          {% else %}
              <p>只有第一次循环打印</p>
          {% endif %}
      {% endfor %}

    3){% csrf_token %}

    • 用于生成csrf_token的标签,用于防止跨站攻击验证
    • 这里其实会生成一个隐藏的input标签,提交时和其他表达标签一并提交给后台
    • 使用时在form标签里面加上{% csrf_token %}即可
      <form action="{% url "xxoo" %}" >
                <input type="text">
                <input type="submit"value="提交">
                {% csrf_token %}
      </form>

    4){% url %}

    • 用于引入路由配置的地址
    # 给url匹配模式起名为 home,别名不需要改,路径就可以随便改了,别的地方要使用这个路径,则用这个别名即可
    url(r'^home', views.home, name='home'),  
    
    
    # 在模板中的使用
    {% url 'home' %}  #模板渲染的时候,被django解析成了这个名字对应的那个url,这个过程叫做反向解析 

    5){% with %}

    • 用更简单的变量名替代复杂的变量名
    • 只在with段内有效
      {% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}

    6){% load %}

    • 加载标签库

    4.3 自定义filter和simple_tag

    1)在app中创建templatetags模块(必须创建,且名字不能改)

    2)创建 .py文件,如my_tags.py

    from django import template
    from django.utils.safestring import mark_safe
    
    register = template.Library()   #register的名字是固定的,不可改变
    
    @register.filter
    def filter_multi(v1,v2):
        return  v1 * v2
    
    @register.simple_tag
    def simple_tag_multi(v1,v2):
        return  v1 * v2
    
    @register.simple_tag
    def my_input(id,arg):
        result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
        return mark_safe(result)

    3)在settings中的INSTALLED_APPS配置当前app

    • 要配置当前app,否则Django无法找到自定义的simple_tag
    • 如果找不到,重启一下Django试试

    4)在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py :{% load my_tags %}

    • 必须在模板的首行导入{% load xxx %},这里是导入my_tags

    5)使用simple_tag和filter

    {% load xxx %}           #首行 
        
     # num=12
    {{ num|filter_multi:2 }}      # filter_multi只能传一个值,前面的num将作为它的第一个参数
                                  # 而冒号后的值将作为第二个参数
    
    {% simple_tag_multi 2 5 %}    # 参数不限,但不能放在if for语句中
    {% simple_tag_multi num 5 %}
    
    # filter_multi可以用在if等语句后,simple_tag不可以
    {% if num|filter_multi:30 > 100 %}
        {{ num|filter_multi:30 }}
    {% endif %}

    4.4 模板的继承

    1)include

    • include标签允许在(模板中)包含其它的模板的内容。
    • 标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串。
    • 每当在多个模板中出现相同的代码时,就应该考虑是否要使用 {% include %} 来减少重复

    2)extends

    • 继承母版master.html,只需在其他页面添加一行:
      {% extends 'master.html' %}

    3)block

    • 对母版中对应位置的内容进行替换,一般对js,css,html三部分内容定义三个bock
    • 在base模版中设置越多的 {% block %} 标签越好
    • 不能在一个模板中定义多个相同名字的block标签

    在母版中定义:

    <div class="menu">
        {% block content %}
        {% endblock %}
    </div>

    在其他页面对母版继承后,再进行对应内容的替换:

    {% extends master.html %}  # 继承母版
    
    # 进行对应位置内容的替换
    {% block content %}
         base页面首页
    {% endblock %}

    4)保留母版内容并添加新特性

    • 使用super即可

    母版html:

    <div class="menu">
    
        {% block content %}
            <div>这是母版测试页面</div>
        {% endblock %}
    </div>

    base.html:

    {% block content %}
        {{ block.super }}
         base页面首页
    {% endblock %}

  • 相关阅读:
    Docker常用命令
    CentOS7.8源码安装nginx
    CentOS7.8搭建STF
    Mac关闭系统安全保护(提示无权删除/usr/bin目录下的文件时)
    Mac本地安装Tcloud-后端
    Mac后台运行进程-终端退出不影响其后台运行
    Docker快速部署TCloud云测试平台--前端
    Docker快速部署TCloud云测试平台--后端
    【项目】项目组件索引
    Netty 直接内存(堆外内存)溢出分析
  • 原文地址:https://www.cnblogs.com/hgzero/p/13211344.html
Copyright © 2020-2023  润新知