Django学习笔记

Django学习笔记

  • 什么是web框架

框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,

就是你用别人搭建好的舞台来做表演。

对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

   最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。

如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。

      正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。

这个接口就是WSGI:Web Server Gateway Interface。

  • MVC和MTV模式
  1. 著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起。
  2. 模型负责业务对象与数据库的对象(ORM),视图负责与用户的交互(页面),控制器(C)接受用户的输入调用模型和视图完成用户的请求。

 

  1. Django的MTV模式本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同,Django的MTV分别代表:
  2.        Model(模型):负责业务对象与数据库的对象(ORM)
  3.        Template(模版):负责如何把页面展示给用户
  4.        View(视图):负责业务逻辑,并在适当的时候调用Model和Template
  5.        此外,Django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

 

 

  • Static之静态文件

静态文件一般都放置在Template里,每一个功能都对应一个static文件建,存放js,css,html以及图片等,配置静态文件路径:

  1. 在setting里配置

 

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/' #取得别名
# 告诉django是绝对路径   !!!元祖要加逗号
# STATICFILES_DIRS=(
#     os.path.join(BASE_DIR,'block/statics'),
#
# )
STATICFILES_DIRS=(
    os.path.join(BASE_DIR,'block','statics'),

)

  1. Html配置路径

 

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% load staticfiles %}
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0
        }

    </style>
</head>
<body>
<h1>hello {{ time }}</h1>

{#<script src="static/jquery-3.1.1.js"></script>静态文件识别文件的方式之一#}


{#<script src="{% static 'jquery-3.1.1.js' %}"></script>#}
<script src="{% static 'jquery-3.1.1.js' %}"></script>
<script>
    $("h1").css("color","red")
</script>
</body>
</html>

 

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    {% load bootstrap3 %}
    {% bootstrap_css %}
    {% bootstrap_javascript %}
    <title>Guest Manage</title>
</head>
<body role="document">


<!--导航栏-->
<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <a class="navbar-brand" href="{% url 'event_manage' %}">Guest Manage System </a>
        </div>
        <div class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li class="active"><a href="{% url 'event_manage' %}">发布会</a></li>
                <li><a href="{% url 'guest_manage' %}">嘉宾</a></li>

            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li class="active"><a href="#">{{ user }}</a></li>
                <li><a href="{% url 'logout' %}">退出</a></li>

            </ul>
        </div>

    </div>

</nav>
<!--发布搜索表单-->
<div class="page-header" style="padding-top: 60px">
    <div id="navbar" class="navbar-collapse collapse">
        <form class="navbar-form" method="get" action="{% url 'search_name'  %}">
            <div class="form-group">
                <input name="name" type="text" placeholder="名称" class="form-control">
            </div>
            <div>
                <button type="submit" class="btn btn-success">搜索</button>
            </div>

        </form>
    </div>
</div>

    <!--发布会列表-->
    <div class="row" style="padding-top: 80px">
        <div class="col-md-6">
            <table class="table table-striped">
                <thead>
                <tr>
                    <th>id</th>
                    <th>名称</th>
                    <th>状态</th>
                    <th>地址</th>
                    <th>时间</th>

                </tr>
                </thead>
                <tbody>
                {% for event in events %}
                    <tr>
                        <td>{{ event.id }}</td>
                        <td>{{ event.name }}</td>
                        <td>{{ event.status }}</td>
                        <td>{{ event.address }}</td>
                        <td>{{ event.start_time }}</td>
                    </tr>
                {% endfor %}
                </tbody>

            </table>

        </div>
    </div>
    <!--列表分页器-->
    <div class="pagination">
    <span class="step-links">
        {% if events.has_previous %}
            <a href="?page={{ events.previous_page_number  }}&&name={{ name }}">previous</a>
        {% endif %}
        <span class="current">
            Page {{ events.number }} of {{ events.paginator.num_pages }}

        </span>
        {% if events.has_next %}
            <a href="?page={{ events.next_page_number }}&name={{ name }}">next</a>
        {% endif %}

    </span>
    </div>
    {% include 'include/pager.html' %}
</body>
</html>

注意:渲染一般是在后台完成的

  • Django的url控制系统

1.url介绍

url配置就像是django所支撑的网站目录。它的本质是url的模式以及要为该url模式调用的视图函数之间的映射表,你就是以这种方式告诉django,对于url调用这段代码,对于那个url调用那段代码。

urlpatterns = [
    path(r'admin/', admin.site.urls),
    path(正则表达式,views视图函数,参数,别名)
]

 

参数说明:

  1. 一个正则表达式字符串
  2. 一个可调用对象,通常为一个视图函数路径的字符串
  3. 可选的传递给视图的默认参数(字典形式)
  4. 一个可选的name参数

 

2.新版的path正则是不起作用,改成re_path

from django.contrib import admin
from django.urls import path,re_path
from blog import views

urlpatterns = [
    path(r'admin/', admin.site.urls),
    path(r'show_time',views.show_time),
    re_path('article/(\d{4})',views.article_year),
    # path(r'article/(?P<year>\d{4}))$',views.article_year),
    # path(r'article/(?P<year>\d{4})/(?P<month>\d{2})/\d+',views.article_year_month),
]

3无命名分组

 

 

 

from django.contrib import admin
from django.urls import path,re_path
from blog import views

urlpatterns = [
    path(r'admin/', admin.site.urls),
    path(r'show_time',views.show_time),
    re_path('article/(\d{4})',views.article_year),
    # path(r'article/(?P<year>\d{4}))$',views.article_year),
    # path(r'article/(?P<year>\d{4})/(?P<month>\d{2})/\d+',views.article_year_month),
]

视图函数:

def article_year(req,y):
    return HttpResponse(y)

 

4.有命名分组

 

 

5.别名

 

 

6.including other urlconfigs(分发)

主逻辑:

from django.contrib import admin
from django.urls import path,re_path,include
from blog import views

urlpatterns = [
    path(r'admin/', admin.site.urls),
    path(r'show_time',views.show_time),
    path('blog/', include('blog.urls')),
]

blog应用:

from django.contrib import admin
from django.urls import path,re_path,include
from blog import views

urlpatterns = [
    re_path('article/(\d{4}$)',views.article_year),
    re_path('article/(?P<year>\d{4})/(?P<month>\d{2})/\d+',views.article_year_month),
    path('registers',views.register ,name='rep'),
]

 

  • 视图函数

1.渲染

 Req:path 发回路径 get_full_path()路径后面跟参数

后台渲染到模板里面,最终把页面返回给前端:

Render

render_to_response

唯一的区别,render多一个参数req,大多数用render,另一个可能存在问题

def register(req):
    if req.method == 'POST':
        print(req.POST.get('user'))
        print(req.POST.get('password'))
        return HttpResponse('suucess!!')

    # return render(req,'register.html')
    return render_to_response('register.html')

2.locals(),把所有句部变量收集起来,打包成一个字典

ef login(req):
    print(req)
    user = 'sdc'
    return render(req, 'login.html', locals())

 

3.redirect跳转到另一个页面

def register(req):
    if req.method == 'POST':
        print(req.POST.get('user'))
        print(req.POST.get('password'))
        user = req.POST.get('user')
        if user == 'yuan':
            return redirect('/login')

        return HttpResponse('suucess!!')

    # return render(req,'register.html')
    return render_to_response('register.html')

 

  • Django之模板语言

 

  1. 两种特殊符号

{{  }}和 {% %}

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

 

 {%ttttt%}是模板标签,{{vvvv}}是模板变量,{{eee|jjj:...}}是过滤器形式

1.1变量

{{ 变量名 }}

  1. 变量名由字母数字和下划线组成。
  2. 点(.)在模板语言中有特殊的含义,用来获取对象的相应属性值。

例子:

def template_test(req):
    l = [11, 22, 33]
    d = {"name": "alex"}

    class Person(object):

        def __init__(self,name,age):
            self.name = name
            self.age = age
        def dream(self):
            return "{} is dream...".format(self.name)
    Alex = Person(name='Alex',age= 34)
    Egon = Person(name='Egon', age=9000)
    Eva_J = Person(name='Eva_J', age=18)
    person_list = [Alex,Egon,Eva_J]
    per_dic = {'guo':'哈哈','fen':'乐乐'}
    return render(req,'templates_list.html',locals())


#      

当templates引擎遇到变量时,引擎使用变量的值代替变量。使用(.)访问变量的属性,比如{{d.name}}。当templates引擎遇到(.)的时候,会按照如下顺序查找:

 

字典查找,例如:foo['bar']  

属性查找,例如:foo.bar  

方法查找,例如:foo.bar()  

list-index查找,例如foo[bar]  

1.2 变量处理函数

  1. add           <h1>{{ d.age|add:2}}</h1> 两个变量的值相加
  2. capfirst         <h1>{{ test|capfirst}}</h1> 首字符大写
  3. cut           <h1>{{yu|cut:’y’}}</h1>                    从字符中移除指定字符
  4. date                   {{now|date|’Y-m-d’}}<br>              格式化日期字符串
  5. default             {{now|default|’空的’}}<br>   如果值是false就替换成设置的默认值,否则就用它本来的值
  6. default_if_none       {{now|default|’空的’}}<br>   如果值是None,就替换成设置的默认值,否则就是用本来的值
  7. safe               {{a|safe}}    后台a标签渲染出来,告诉前台是安全的
  8. autoescape

使用形式: 

{% autoescape off %} 

(内容) 

{% endautoescape %} 

  1. {{vlues|filesizeformat}}<br>
  2. {{vslues|first}}<br>
  3. {{vslues|length}}<br>
  4. {{value8|slice|’-1’}}<br>
  5. {{values|urlencode}}<br>

意义:当某块内容不需要自动转义的时候,这样写就可以了。当然如果块内某些地方需要转义的话,调用filter也可以。

2模板的大致结构(后面有详细)

Django的templates(templates:模板),它是一个string文本。templates用来分离一个文档的表现形式和内容(也可以说成数据)。templates定义了placeholder(placeholder:占位符)和表示多种逻辑的tags(tags:标签)来规定文档如何展现。通常templates用来输出HTML,但是Django的templates也能生成其他基于文本的形式。

例子:

<html>

<head><title>Ordering notice</title></head>

<body>

<h1>Ordering notice</h1>

<p>Dear {{ person_name }},</p>

<p>Thanks for placing an order from {{ company }}. It's scheduled to

ship on {{ ship_date|date:"F j, Y" }}.</p>

<p>Here are the items you've ordered:</p>

<ul>

{% for item in item_list %}

    <li>{{ item }}</li>

{% endfor %}

</ul>

{% if ordered_warranty %}

    <p>Your warranty information will be included in the packaging.</p>

{% else %}

    <p>You didn't order a warranty, so you're on your own when

    the products inevitably stop working.</p>

{% endif %}

<p>Sincerely,<br />{{ company }}</p>

</body>

</html>

 

例子中,

 

用两个大括号括起来的文字(例如 {{ person_name }} )称为 变量(variable) 。这意味着在此处插入指定变量的值。

 

被大括号和百分号包围的文本(例如 {% if ordered_warranty %} )是 模板标签(template tag) 。标签(tag)定义比较明确,即: 仅通知模板系统完成某些工作的标签。

 

 

这个例子中的模板包含一个for标签( {% for item in item_list %} )和一个if 标签({% if ordered_warranty %} )

 

for标签类似Python的for语句,可让你循环访问序列里的每一个项目。 if 标签,正如你所料,是用来执行逻辑判断的。 在这里,tag标签检查ordered_warranty值是否为True。如果是,模板系统将显示{% if ordered_warranty %}和{% else %}之间的内容;否则将显示{% else %}和{% endif %}之间的内容。{% else %}是可选的。

 

就是通俗一点说, {{xxx}}这个为变量。{% %} 为语法使用。在整体上模版的结构就是如此。

 

至此了解到模版的大致结构。现在了解一下模版标签。

 

  1. 标签
  • if/else标签

{% if %} 标签会考察一个变量,如果这个变量为真(即,变量存在,非空,不是布尔值假),系统会显示在 {% if %} 和 {% endif %} 之间的任何内容

例如:

 

{% if today_is_weekend %}

 

<p>Welcome to the weekend!</p>

 

{% endif %}

 

{% else %} 标签是可选的

 

 

{% if today_is_weekend %}

{% elif d.age>10%}

 <h1>d.age</h1>

 

<p>Welcome to the weekend!</p>

 

 

{% else %}

 

 

<p>Get back to work.</p>

 

 

{% endif %}

 

{% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not ),但不允许在同一个标签中同时使用 and 和 or ,因为逻辑上可能模糊的

 

  • for标签

for标签用于迭代序列中的各个元素。 

 

与 Python 的 for 语句类似,语法是for X in Y。其中 Y 是要迭代的序列, X 是单次循环中使用的变量。每次迭代时,模板系统会渲染 {% for %} 和 {% endfor %} 之间的内容。

 

1.正向迭代

 

<ul>

{% for athlete in athlete_list %}

    <li>{{ athlete.name }}</li>

{% endfor %}

</ul>

2.加入reversed标签,反向迭代

 

{% for athlete in athlete_list reversed %}

{% endfor %}

3.对二元组解包

{% for x, y in points %}

    <p>There is a point at {{ x }},{{ y }}</p>

{% endfor %}

4.字典解包

 

{% for key, value in data.items %}

    {{ key }}: {{ value }}

{% endfor %}

5.判断列表是否为空

在执行循环之前先检测列表的大小是一个通常的做法,当列表为空时输出一些特别的提示。

{% if athlete_list %}

    {% for athlete in athlete_list %}

        <p>{{ athlete.name }}</p>

    {% endfor %}

{% else %}

    <p>There are no athletes. Only computer programmers.</p>

{% endif %}

因为这种做法十分常见,所以for 标签支持一个可选的{% empty %} 分句,通过它,我们可以定义当列表为空时的输出内容。

 

{% for athlete in athlete_list %}

    <p>{{ athlete.name }}</p>

{% empty %}

<p>There are no athletes. Only computer programmers.</p>
{% endfor %}

6 for标签内部模板变量forloop

 

在每个{% for %}循环里有一个称为forloop 的模板变量。 

 

forloop.counter 总是一个表示当前循环的执行次数的整数计数器。这个计数器是从1开始的,所以在第一次循环时 forloop.counter 将会被设置为1。 

{% for item in todo_list %}

<p>{{ forloop.counter }}: {{ item }}</p>

{% endfor %}

forloop.counter0 类似于 forloop.counter ,但是它是从0计数的。 第一次执行循环时这个变量会被设置为0。

forloop.revcounter的值是一个整数,表示循环中剩余的元素数量。第一次循环时, forloop.revcounter 的值是序列中要遍历的元素总数。最后一次循环时, forloop.revcounter的值为 1 。

forloop.revcounter0 与 forloop.revcounter类似,不过索引是基于零的。第一次循环时, forloop.revcounter0的值是序列中元素数量减去一。最后一次循环时, forloop.revcounter0 的值为 0 。

forloop.first 是个布尔值,第一次循环时为 True 。需要特殊处理第一个元素时很方便。

{% for object in objects %}

    {% if forloop.first %}

        <li class="first">

    {% else %}

        <li>

    {% endif %}

    {{ object }}

    </li>

{% endfor %}

forloop.last是个布尔值,最后一次循环时为True 。经常用它在一组链接之间放置管道符号(|)。

{% for link in links %}

    {{ link }}{% if not forloop.last %} | {% endif %}

{% endfor %}

此外,还经常用它在一组单词之间放置逗号(,): 

 

<p>Favorite places:</p>

{% for p in places %}

    {{ p }}{% if not forloop.last %}, {% endif %}

{% endfor %}

forloop.parentloop 是一个指向当前循环的上一级循环的 forloop 对象的引用(在嵌套循环的情况下)。

{% for country in countries %}

    <table>

    {% for city in country.city_list %}

        <tr>

        <td>Country #{{ forloop.parentloop.counter }}</td>

        <td>City #{{ forloop.counter }}</td>

        <td>{{ city }}</td>

        </tr>

 

    {% endfor %}

    </table>

{% endfor %}

需要注意的是,

 

forloop 变量只在循环内部可用。模板解析器遇到 {% endfor %} 时, forloop 随之消失。 

 

如果有名为 forloop 的模板变量(不建议这么做),在 {% for %} 块中会重命名为 forloop.parentloop 。

 

ifchanged

          使用形式:

          (a)如果直接检测循环变量是否变化,那么使用:

              {% ifchanged %}  

                  (内容)

              {% endifchanged %}

          (b)如果检测循环变量的某个dot变量,例如循环变量是date,那么检测date.hour,那么使用:

              {% ifchanged date.hour%}  

                  (内容)

              {% endifchanged %}    

          (c)ifchanged也可以加上一个{% else %}语句

          意义:检测本次循环的值和上一次循环的值一样不一样,只能用在循环里面。

(三)ifequal / ifnotequal 标签

 

对比两个值是否相对,ifequal相等,ifnotequal不相等。

 

只有模板变量,字符串,整数和小数可以作为 {% ifequal %} 标签的参数。其他任何类型,例如Python的字典类型、列表类型、布尔类型,不能用在 {% ifequal %} 中。 

 

下面的例子比较两个模板变量 user 和 currentuser :

 

{% ifequal user currentuser %}

    <h1>Welcome!</h1>

{% endifequal %}

参数可以是硬编码的字符串,随便用单引号或者双引号引起来,所以下列代码都是正确的:

 

{% ifequal section 'sitenews' %}

    <h1>Site News</h1>

{% endifequal %}

和 {% if %} 类似, {% ifequal %} 支持可选的 {% else%} 标签

 

(四)一些常用标签

 

(1)autoescape

使用形式: 

{% autoescape off %} 

(内容) 

{% endautoescape %} 

意义:当某块内容不需要自动转义的时候,这样写就可以了。当然如果块内某些地方需要转义的话,调用filter也可以。

 

(2)block

使用形式: 

{% block %} 

(定义块内容) 

{% endblock %} 

意义:定义一个块,该块能够被继承他的子孙模板重写

 

(3)comment

使用形式: 

{% comment %} 

(内容) 

{% endcomment %} 

意义:模板系统会忽略该标签内部的所有内容。

 

(4)cycle

使用形式: 

例如: 

<\tr class=”{% cycle list%}”> 

… 

<\/tr> 

意义:在循环时轮流使用给定的字符串列表中的值。

 

(5)extends

使用形式:{% extends “base.html” %}或者{% extends variable %}变量可以是一个字符串,也可以是一个模板对象。 

意义:表示本模板要对指定的父模板进行扩展。

 

(6)filter

使用形式: 

{%filter force_escape|lower%} 

(内容) 

{%endfilter%} 

意义:将filter 标签圈定的内容执行过滤器操作。

 

(7)firstof

使用形式:{%firstof var1 var2 var3%} 

意义:输出第一个值不等于False的变量 

等价于: 

{% if var1 %} 

{{ var1 }} 

{% else %} 

{% if var2 %} 

{{ var2 }} 

{% else %} 

{% if var3 %} 

{{ var3 }} 

{% endif %} 

{% endif %} 

{% endif %}

 

(8)for

使用形式: 

{% for variable in list/dict %} 

(使用variable) 

{% endfor%} 

意义:循环list中的每个值,进行相应的输出 

注意:(a)也可以反向遍历{% for variable in list/dict reversed %} 

(b)也可以{% for x, y in points %} points中的每个元素为 (x,y) 

(c)也可以{% for key,value in data.items %} data是一个dictionary 

for loop中定义的一些内建变量 

forloop.counter 当前的迭代器数目(从1开始) 

forloop.counter0 当前的迭代器数目(从0开始) 

forloop.revcounter 当前的反向迭代器数目(从1开始) 

forloop.revcounter0 当前的反向迭代器数目(从0开始) 

forloop.first 值为True,如果是第一次通过迭代器 

forloop.last 值为True,如果是最后一次通过迭代器 

forloop.parentloop 对于嵌套循环,这是当前循环的上一层循环

 

(9)for … empty

使用形式如下: 

{% for varibale in list %} 

(内容1) 

{% empty %} 

(内容2) 

{% endfor %} 

意义:当list是空的时候,能够执行内容2,其形式等同于,先if判断list是否存在,然后在根据情况做什么操作。

 

(10)if

使用形式如下 : 

{% if variable %} 

(内容1) 

{% else %} 

(内容2) 

{% endif %} 

注意:variable中可以使用and or 或者not,但是有一条必须记住,就是不允许and 和 or一起使用

 

(11)ifchanged

使用形式: 

(a)如果直接检测循环变量是否变化,那么使用: 

{% ifchanged %} 

(内容) 

{% endifchanged %} 

(b)如果检测循环变量的某个dot变量,例如循环变量是date,那么检测date.hour,那么使用: 

{% ifchanged date.hour%} 

(内容) 

{% endifchanged %} 

(c)ifchanged也可以加上一个{% else %}语句 

意义:检测本次循环的值和上一次循环的值一样不一样,只能用在循环里面。

 

(12)ifequal

使用形式: 

{% ifequal variable1 variable2 %} 

… 

{% endifequal %} 

意义:判断两个变量是否相等。

 

(13)ifnotequal

使用与(12)相同

 

(14)include

使用形式:{% include “foo/bar.html” %}或者{% include template_name %} 

意义:将另外一个模板文件中的内容添加到该文件中。注意区别extend是继承。

 

(15)now

使用形式:{% now “jS F Y H:i “%},注意存在需要转义的情况例如{% now “jS o\f F” %},因为f是格式化字符串

 

具体的格式化字符串如下所示

 

a ‘a.m.’ or ‘p.m.’ (Note that this is slightly different than PHP’s output, because this includes periods to match Associated Press style.) ‘a.m.’ 

A ‘AM’ or ‘PM’. ‘AM’ 

b Month, textual, 3 letters, lowercase. ‘jan’ 

B Not implemented. 

d Day of the month, 2 digits with leading zeros. ‘01’ to ‘31’ 

D Day of the week, textual, 3 letters. ‘Fri’ 

f Time, in 12-hour hours and minutes, with minutes left off if they’re zero. Proprietary extension. ‘1’, ‘1:30’ 

F Month, textual, long. ‘January’ 

g Hour, 12-hour format without leading zeros. ‘1’ to ‘12’ 

G Hour, 24-hour format without leading zeros. ‘0’ to ‘23’ 

h Hour, 12-hour format. ‘01’ to ‘12’ 

H Hour, 24-hour format. ‘00’ to ‘23’ 

i Minutes. ‘00’ to ‘59’ 

I Not implemented. 

j Day of the month without leading zeros. ‘1’ to ‘31’ 

l Day of the week, textual, long. ‘Friday’ 

L Boolean for whether it’s a leap year. True or False 

m Month, 2 digits with leading zeros. ‘01’ to ‘12’ 

M Month, textual, 3 letters. ‘Jan’ 

n Month without leading zeros. ‘1’ to ‘12’ 

N Month abbreviation in Associated Press style. Proprietary extension. ‘Jan.’, ‘Feb.’, ‘March’, ‘May’ 

O Difference to Greenwich time in hours. ‘+0200’ 

P Time, in 12-hour hours, minutes and ‘a.m.’/’p.m.’, with minutes left off if they’re zero and the special-case strings ‘midnight’ and ‘noon’ if appropriate. Proprietary extension. ‘1 a.m.’, ‘1:30 p.m.’, ‘midnight’, ‘noon’, ‘12:30 p.m.’ 

r RFC 2822 formatted date. ‘Thu, 21 Dec 2000 16:01:07 +0200’ 

s Seconds, 2 digits with leading zeros. ‘00’ to ‘59’ 

S English ordinal suffix for day of the month, 2 characters. ‘st’, ‘nd’, ‘rd’ or ‘th’ 

t Number of days in the given month. 28 to 31 

T Time zone of this machine. ‘EST’, ‘MDT’ 

U Not implemented. 

w Day of the week, digits without leading zeros. ‘0’ (Sunday) to ‘6’ (Saturday) 

W ISO-8601 week number of year, with weeks starting on Monday. 1, 53 

y Year, 2 digits. ‘99’ 

Y Year, 4 digits. ‘1999’ 

z Day of the year. 0 to 365 

Z Time zone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive.

 

(16)spaceless

使用形式:{% spaceless %} 

(内容) 

{% endspaceless %} 

意义:删除包围内容中的所有tab或者回车字符。

 

(17)template

使用形式:{% templatetag %} 

意义:模板系统本身没有转义的概念,因此如果要输出一个像“{%”这样的东东,就需要采用这种方式,否则就会语法错误 

其参数有:

 

openblock {% 

closeblock %} 

openvariable {

closevariable }} 

openbrace { 

closebrace } 

opencomment {# 

closecomment #}

 

(18)with

使用形式: 

{% with “expensive var1” as var2 %} 

{% endwith %} 

意义:当一个变量的访问消耗很大的模板解析时,可以用另外一个变量替换它,这种替换只有在with内部有效。

 

(19)url

使用形式:{% url path.to.some_view arg1,arg2 %} 

意义:给定某个module中函数的名字,给定参数,那么模板引擎给你一个URL,从而避免硬编码URL到代码中

 

注意:前提是URLconf中存在相应的映射,如果URLconf中没有该映射,那么会抛出异常, 

这是可以选择使用 

{% url path.to.view arg1 ,arg2 as the_url %} 

<\a href=”{{ the_url }}”>Link to optional stuff \<\/\a> 

其实这相当于 

{% url path.to.view as the_url %} 

{% if the_url %} 

<a href=”{{ the_url }}”>Link to optional stuff </a> 

{% endif %}

 

csrf_token

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

 

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

 

 

过滤器

 

通过过滤器可以改变变量的显示方式,过滤器的形式是:{{ variable | filter }},管道符号'|'代表使用过滤器。

 

例如:

 

{{value|default:"nohting"}}

表示当value为空或None时就会显示”nothing“。

 

Django中有几十个内建的过滤器。

 

先看过滤器的使用说明:

 

1.过滤器能够采用链式的方式使用

 

例如:

 

{{ text | escape | linebreaks }}

2.过滤器可以带参数

 

例如:

 

{{ bio|truncatewords:30 }}

如果参数中带有空格,那么需要用引号引起来,例如:

 

{{ list | join : ", "}}

下面是常用的Django内建过滤器:

 

(1)add

 

例如:

 

{{ value | add: "2"}}

意义:把value的值增加2。比如,value的值是4,那么输出为6。注意,add首先尝试把两个值当作整数相加,如果失败,就尝试把两个值组合在一起(比如遇到字符串或list的时候),其他失败的情况返回一个空字符串。

 

例如:

 

{{first|add:second}},first=[1,2,3],second=[4,5,6]

输出结果为[1,2,3,4,5,6]。(小白我一开始以为是[5,7,9]。。。。。)

 

(2)addslashes

 

{{ value | addslashes }}

意义:在value中引号(单引号和双引号)前增加反斜线

 

例如:

 

{{value|addslashes}},value=I'm using Django

输出结果为I\'m using Django

 

(3)capfirst

 

{{ value | capfirst }}

意义:value的第一个字符转化成大写形式

 

(4)cut

 

{{ value | cut:arg}}

意义:移出value中包含arg的字符串。如果value是"String with spaces",arg是" ",那么输出结果是"Stringwithspaces"

 

(5)date

 

意义:将日期格式数据按照给定的格式输出。

 

{{ value | date:"D d M Y" }}

如果value是一个datetime对象,那么输出将是字符串"Wed 09 Jan 2008"。

 

下面的例子没有格式化字符串,这时候格式化字符串会自动采用DATE_FORMAT所设置的形式。

 

 {{ value | date }}

(6)default

 

意义:如果value的意义是False,那么输出使用缺省值。

 

{{ value | default: "nothing" }}

如果value是"",输出将是"nothing"。

 

(7)default_if_none

 

{{ value | default_if_none:"nothing" }}

意义:如果value是None,那么输出将使用缺省值(这里是"nothing")

 

(8)dictsort

 

{{ value | dictsort:"name"}}

意义:如果value的值是一个字典,那么返回值是按照关键字排序的结果。

 

例如,如果value是 [ {'name': 'zed', 'age': 19}, {'name': 'amy', 'age': 22}, {'name': 'joe', 'age': 31}, ] 那么,输出是: [ {'name': 'amy', 'age': 22}, {'name': 'joe', 'age': 31}, {'name': 'zed', 'age': 19}, ]

 

(9)dictsortreversed

 

意义:如果value的值是一个字典,那么返回值是按照关键字排序的结果的反序。

 

使用形式与上述(8)完全相同。

 

(10)divisibleby

 

{{ value | divisibleby:arg}}

意义:如果value能够被arg整除,那么返回值将是True

 

例如value是21,arg是3,那么输出将是True

 

(11)escape

 

{{ value | escape}}

意义:替换value中的某些字符,以适应HTML格式,包括:

 

< 会被转换为 <

 

> 会被转换位 >

 

'(单引号)会被转换为 '

 

" (双引号)会被转换为 "

 

& 会被转换为 &

 

注意:escape仅仅在输出的时候才起作用,所以escape不能够用在链式过滤器的中间,它总是最后一个过滤器。如果想在链式过滤器的中间使用,那么可以使用force_escape。

 

(12)escapejs

 

{{ value | escapejs }}

意义:替换value中的某些字符,以适应JavaScript和Json格式

 

(13)filesizeformat

 

{{ value | filesizeformat }}

意义:格式化value,使其成为易读的文件大小

 

(14)first

 

{{ value | first }}

意义:返回列表中的第一个Item

 

如果value是列表['a','b','c'],那么输出将是'a'

 

(15)floatformat

 

{{ value | floatformat}}或者{{value|floatformat:arg}}

arg可以是正数,也可以是负数。没有参数的floatformat相当于floatformat:-1

 

如果不带arg,那么引擎会四舍五入,同时最多只保留一位小数

34.23234    {{ value|floatformat }}  34.2  

34.00000    {{ value|floatformat }} 34  

34.26000    {{ value|floatformat }} 34.3  

如果arg是正数,那么引擎会四舍五入,同时保留arg个位的小数

34.23234    {{ value|floatformat:3 }}   34.232  

34.00000    {{ value|floatformat:3 }}   34.000  

34.26000    {{ value|floatformat:3 }}   34.260 

如果arg是负数,那么引擎会四舍五入,如果有小数部分,那么保留arg个位的小数,否则没有任何小数部分

34.23234    {{ value|floatformat:"-3" }}    34.232  

34.00000    {{ value|floatformat:"-3" }}    34  

34.26000    {{ value|floatformat:"-3" }}    34.26  

 

 

(16)get_digit 

 

使用形式:{{ value | get_digit:"arg"}}

 

例如,如果value是123456789,arg是2,那么输出是8 

 

意义:给定一个数字,返回,请求的数字,记住:1代表最右边的数字,如果value不是合法输入,那么会返回所有原有值。

 

 

 

(17)iriencode 

 

使用形式:{{value | iriencode}} 

 

意义:如果value中有非ASCII字符,那么将其进行转化成URL中适合的编码,如果value已经进行过URLENCODE,该操作就不会再起作用。

 

 

 

(18)join 

 

使用形式:{{ value | join:"arg"}}

 

如果value是['a','b','c'],arg是'//'

 

那么输出是a//b//c 

 

意义:使用指定的字符串连接一个list,作用如同python的str.join(list)

 

 

 

19. last 

 

使用形式:{{ value | last }} 

 

意义:返回列表中的最后一个Item

 

 

 

20. length 

 

使用形式:{{ value | length }} 

 

意义:返回value的长度。

 

 

21. length_is 

 

使用形式:{{ value | length_is:"arg"}} 

 

意义:返回True,如果value的长度等于arg的时候

 

例如:如果value是['a','b','c'],arg是3,那么返回True

 

 

 

22. linebreaks 

 

使用形式:{{value|linebreaks}} 

 

意义:value中的"\n"将被替代,并且整个value使用

 

(注意这里是个换行!!!!)包围起来,从而适和HTML的格式

 

23. linebreaksbr

 

 使用形式:{{value |linebreaksbr}} 

 

意义:value中的"\n"将被<br/>替代

 

 

 

24. linenumbers 

 

使用形式:{{value | linenumbers}} 

 

意义:显示的文本,带有行数。

 

 

 

25. ljust

 

 使用形式:{{value | ljust}} 

 

意义:在一个给定宽度的字段中,左对齐显示value

 

 

 

26. center

 

 使用形式:{{value | center}}

 

 意义:在一个给定宽度的字段中,中心对齐显示value

 

 

 

27. rjust 

 

使用形式:{{value | rjust}} 

 

意义:在一个给定宽度的字段中,右对齐显示value

 

 

 

28. lower 

 

使用形式:{{value | lower}} 

 

意义:将一个字符串转换成小写形式

 

 

 

29. make_list 

 

使用形式:{{value | make_list}} 

 

意义:将value转换成一个list,对于字符串,转换成字符list;对于整数,转换成整数list 

 

例如value是Joel,那么输出将是[u'J',u'o',u'e',u'l'];value是123,那么输出将是[1,2,3]

 

 

 

30. pluralize 

 

使用形式:{{value | pluralize}},或者{{value | pluralize:"es"}},或者{{value | pluralize:"y,ies"}} 

 

意义:如果value不是1,则返回一个复数后缀,缺省的后缀是's'

 

 

 

31. random 

 

使用形式:{{value | random}} 

 

意义:从给定的list中返回一个任意的Item

 

 

 

32. removetags 

 

使用形式:{{value | removetags:"tag1 tag2 tag3..."}} 

 

意义:删除value中tag1,tag2....的标签。

 

例如,如果value是

 

                <b>Joel</b> <button>is</button> a <span>slug</span> 

 

                tags是"b span",

 

那么输出将是:Joel <button>is</button> a slug

 

 

 

33. safe

 

 使用形式:{{value | safe}} 

 

意义:当系统设置autoescaping打开的时候,该过滤器使得输出不进行escape转换

 

 

 

34. safeseq 

 

与上述safe基本相同,但有一点不同的就是:safe是针对字符串,而safeseq是针对多个字符串组成的sequence

 

 

35. slice

 

 使用形式:{{some_list | slice:":2"}} 

 

意义:与python语法中的slice相同,:2表示第一的第二个元素

 

 

 

36. slugify 

 

使用形式:{{value | slugify}} 

 

意义:将value转换成小写形式,同事删除所有分单词字符,并将空格变成横线 

 

例如:如果value是Joel is a slug,那么输出将是joel-is-a-slug

 

 

 

37. stringformat 

 

这个不经常用,先不说 

 

简单举个例子:如果value是 10,那么输出 1.000000E+01

 

 

 

38. striptags 

 

使用形式:{{value | striptags}} 

 

意义:删除value中的所有HTML标签

 

 

 

39. time 

 

使用形式:{{value | time:"H:i"}}或者{{value | time}} 

 

意义:格式化时间输出,如果time后面没有格式化参数,那么输出按照TIME_FORMAT中设置的进行。

 

 

 

40. title 

 

转换一个字符串成为title格式。 如: value是 "my first post",输出: "My First Post"

 

 

 

41. truncatewords 

 

使用形式:{{value | truncatewords:2}} 

 

意义:将value切成truncatewords指定的单词数目 

 

例如,如果value是Joel is a slug 那么输出将是:Joel is ...

 

 

 

42. truncatewords_html 

 

使用形式同(39) 

 

意义:truncation点之前如果某个标签打开了,但是没有关闭,那么在truncation点会立即关闭。 因为这个操作的效率比truncatewords低,所有只有在value是html格式时,才考虑使用。

 

 

 

43. upper 

 

转换一个字符串为大写形式

 

 

 

44. urlencode 

 

将一个字符串进行URLEncode

 

 

 

45. urlize 

 

意义:将一个字符串中的URL转化成可点击的形式。 

 

使用形式:{{ value | urlize }} 

 

例如,如果value是Check out www.djangoproject.com,那么输出将是: Check out www.djangoproject.com

 

 

 

46. urlizetrunc 

 

使用形式:{{ value | urlizetrunc:15}} 

 

意义:与(43)相同,但是有一点不同就是现实的链接字符会被truncate成特定的长度,后面以...现实。

 

 

 

47. wordcount

 

 返回字符串中单词的数目

 

 

 

48. wordwrap 

 

使用形式:{{value | wordwrap:5}} 

 

意义:按照指定的长度包装字符串 

 

例如,如果value是Joel is a slug,那么输出将会是: Joel is a slug

 

 

 

49. timesince 

 

使用形式:{{value | timesince:arg}} 

 

意义:返回参数arg到value的天数和小时数 

 

例如,如果 blog_date 是一个日期实例,表示 2006-06-01 午夜, 而 comment_date 是一个日期实例,表示 2006-06-01 早上8点, 那么 {{ comment_date|timesince:blog_date }} 将返回 "8 hours".

 

 

 

50. timeuntil 

 

使用形式:{{value | timeuntil}} 

 

意义:与(47)基本相同,一个不同点就是,返回的是value距离当前日期的天数和小时数。

 

 

注释写法

1

{# ... #}

 

 

Django 模板概念和运用

母板

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta http-equiv="x-ua-compatible" content="IE=edge">

  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Title</title>

  {% block page-css %}

   

  {% endblock %}

</head>

<body>

 

<h1>这是母板的标题</h1>

 

{% block page-main %}

 

{% endblock %}

<h1>母板底部内容</h1>

{% block page-js %}

 

{% endblock %}

</body>

</html>

 

 

注意:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换。

 

继承母板

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

 

1

{% extends 'layouts.html' %}

块(block)

通过在母板中使用{%block xxx%}来定义"块"。

 

在子页面中通过定义母板中的block名来对应替换母板中相应的内容。

 

1

2

3

4

5

{% block page-main %}

  <p>世情薄</p>

  <p>人情恶</p>

  <p>雨送黄昏花易落</p>

{% endblock %}

组件

可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。

 

1

{% include 'navbar.html' %}

静态文件相关

1

2

{% load static %}

<img src="{% static "images/hi.jpg" %}" alt="Hi!" />

引用JS文件时使用:

 

1

2

{% load static %}

<script src="{% static "mytest.js" %}"></script>

某个文件多处被用到可以存为一个变量

 

1

2

3

{% load static %}

{% static "images/hi.jpg" as myphoto %}

<img src="{{ myphoto }}"></img>

使用get_static_prefix

 

1

2

{% load static %}

<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />

或者

 

1

2

3

4

5

{% load static %}

{% get_static_prefix as STATIC_PREFIX %}

 

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />

<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

 

include 模板标签 

内建模板标签:该标签允许在(模板中)包含其它的模板的内容。就是html里面的iframe 

下面这两个例子都包含了 nav.html 模板。这两个例子是等价的,它们证明单/双引号都是允许的。

 

{% include 'nav.html' %}

{% include "nav.html" %}

1

2

下面的例子包含了 includes/nav.html 模板的内容:

 

{% include 'includes/nav.html' %}

1

下面的例子包含了以变量 template_name 的值为名称的模板内容:

 

{% include template_name %} 

 

 

模板继承

 

 

 

本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。 

就是说,比如每个网页都包含<HTML></HTML> 等重复的代码 

第一步是定义 基础模板 , 该框架之后将由 子模板 所继承。 以下是我们目前所讲述范例的基础模板

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

<html lang="en">

<head>

    <title>{% block title %}{% endblock %}</title>

</head>

<body>

    <h1>My helpful timestamp site</h1>

    {% block content %}{% endblock %}

    {% block footer %}

    <hr>

    <p>Thanks for visiting my site.</p>

    {% endblock %}

</body>

</html>

这个叫做 base.html 的模板定义了一个简单的 HTML 框架文档,我们将在本站点的所有页面中使用。 

 

子模板的作用就是重载、添加或保留那些块的内容。 

 

我们使用一个以前已经见过的模板标签: {% block %} 。 所有的 {% block %} 标签告诉模板引擎,子模板可以重载这些部分。 每个{% block %}标签所要做的是告诉模板引擎,该模板下的这一块内容将有可能被子模板覆盖。 

现在我们已经有了一个基本模板,我们可以修改 current_datetime.html 模板来 使用它。

{% extends "base.html" %}

 

{% block title %}The current time{% endblock %}

{% block content %}

<p>It is now {{ current_date }}.</p>

{% endblock %}

模板引擎发现了 {% extends %} 标签, 注意到该模板是一个子模板。 模板引擎立即装载其父模板,即本例中的 base.html 。 

模板引擎注意到 base.html 中的三个 {% block %} 标签,并用子模板的内容替换这些 block 。因此,引擎将会使用我们在 { block title %} 中定义的标题,对 {% block content %} 也是如此。 所以,网页标题一块将由 {% block title %}替换,同样地,网页的内容一块将由 {% block content %}替换。 

 

注意由于子模板并没有定义 footer 块,模板系统将使用在父模板中定义的值。 父模板 {% block %} 标签中的内容总是被当作一条退路。

 

 

 

 

 

使用继承的一种常见方式是下面的三层法:

 

创建 base.html 模板,在其中定义站点的主要外观感受。 这些都是不常修改甚至从不修改的部分。

 

为网站的每个区域创建 base_SECTION.html 模板(例如, base_photos.html 和 base_forum.html )。这些模板对 base.html 进行拓展,并包含区域特定的风格与设计。

 

为每种类型的页面创建独立的模板,例如论坛页面或者图片库。 这些模板拓展相应的区域模板。

 

这个方法可最大限度地重用代码,并使得向公共区域(如区域级的导航)添加内容成为一件轻松的工作。

 

 

 

 

 

以下是使用模板继承的一些诀窍:

 

如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。 否则,模板继承将不起作用。

 

一般来说,基础模板中的 {% block %} 标签越多越好。 记住,子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越多越好。

 

如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 {% block %} 中。

 

如果你需要访问父模板中的块的内容,使用 {{ block.super }}这个标签吧,这一个魔法变量将会表现出父模板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。

 

不允许在同一个模板中定义多个同名的 {% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。 也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。

 

{% extends %} 对所传入模板名称使用的加载方法和 get_template() 相同。 也就是说,会将模板名称被添加到 TEMPLATE_DIRS 设置之后。

 

多数情况下, {% extends %} 的参数应该是字符串,但是如果直到运行时方能确定父模板名,这个参数也可以是个变量。 这使得你能够实现一些很酷的动态功能。

 

 

 

 

 

如何在视图中使用模板 

 

模版是以Html形式显示的。要在django中使用,首先要告诉模版存放在那里。也就是模版加载。打开你的settings.py配置文件,配置如下: 

 

你可以任意指定想要的目录,只要运行 Web 服务器的用户可以读取该目录的子目录和模板文件

使用方式: 

1.render 

2.render_to_response 

3.get_template() 

个人比较支持第1和2的方式 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值