草稿二

• for循环---表格

views

def index(request):

context={
    'books':[
        {'name':'xiyouji','author':'k','price':99},
        {'name':'hongloumeng','author':'j','price':90},
        {'name':'shuihuzhuan','author':'a','price':106},
        {'name':'sanguoyanyi','author':'b','price':112},
    ],
    'person':{
        'username':'Jim Green',
        'age':20,
        'sex':'man'
    }
}
return render(request,'index.html',context=context)

html

<body>
......
<table>
<thead>
<tr>
<td>bookname</td> # 表头
<td>author</td> # 表格的基本格式就是这样
<td>price</td>
</tr>
</thead>
<tbody>
{% for book in books %} # 表身
<tr>
<td>{{ book.name }}</td>
<td>{{ book.author }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}

    </tbody>
</table>

</body>

效果:

bookname author price
xiyouji k 99
hongloumeng j 90
shuihuzhuan a 106
sanguoyanyi b 112

• forloop.counter---返回数值(循环的次数,从1开始,只能用于for循环)
forloop.counter0---从0开始计数
forloop.recounter---counter的倒序(比如counter是1-4,那么recounter就是4-1)
forloop.recounter0---倒序末位数是0
示例:

html

<body>
......
<table>
<thead>
<tr>
<td>number</td> # 添加计数
<td>bookname</td>
<td>author</td>
<td>price</td>
</tr>
</thead>
<tbody>
{% for book in books %}
<tr>
<td>{{ forloop.counter }}</td> # forloop.counter计数
<td>{{ book.name }}</td>
<td>{{ book.author }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}

    </tbody>
</table>

</body>

效果:

number bookname author price
1 xiyouji k 99
2 hongloumeng j 90
3 shuihuzhuan a 106
4 sanguoyanyi b 112

• forloop.first/last---对应 第一次/最后一次 循环
下述示例,对表格的第一行和最后一行渲染颜色:

<table>
    <thead>
        <tr>
            <td>number</td>
            <td>bookname</td>
            <td>author</td>
            <td>price</td>
        </tr>
    </thead>
    <tbody>
        {% for book in books %}
            {% if forloop.first %} # 第一次循环,渲染样式
                <tr style="background-color: green">
            {% elif forloop.last %} # 最后一次循环,渲染样式
                <tr style="background-color: brown">
            {% else %}
                <tr> # 如果不是第一次/最后一次,那么就返回普通标签
            {% endif %}
                <td>{{ forloop.counter }}</td>
                <td>{{ book.name }}</td>
                <td>{{ book.author }}</td>
                <td>{{ book.price }}</td>
        </tr> # 这个结束标签不能遗漏
        {% endfor %}

    </tbody>
</table>

看效果,成功渲染

• for...empty...示例:

views

from django.shortcuts import render
from django.template.loader import render_to_string
from django.http import HttpResponse

def index(request):

context={
    'books':[
        {'name':'sanguoyanyi','author':'shianang','price':100},
        {'name':'shuihuzhuan','author':'luoguanz','price':120},
        {'name':'hongloumeng','author':'caoxueqing','price':180},
        {'name':'xiyouji','author':'wuchengen','price':200},
    ],
    'person':{
        'name':'Kate Green',
        'age':18,
        'sex':'woman',
    },
    'comments':[], # 这里只有为空,才会显示template的'There is no comment',值为None或者''都不行
}
#return render(request,'index.html',context=dict(person=p))
return render(request,'index.html',context=context)

{% for comment in comments %}
<p>{{ comment }}</p>
{% empty %}
<p>There is no any comment.</p>
{% endfor %}

• with用法:定义模板变量

<1>基础用法示例:

views

def index(request):

context={
    ......
    'persons':[
        'Jim Green',
        'Kate Green',
        'Li Lei',
        'Han meimei',
    ],
}
return render(request,'index.html',context=context)

html

......
<body>
<p>{{ persons.0 }}</p> # 使用这种定义,显示'Jim Green'
<p>{{ persons.0 }}</p>
<p>{{ persons.0 }}</p>
</body>

现在换一种写法:

<body>
{% with name1=persons.0 %} # with相当于js的var,注意等号两边不能使用空格,否则语法错误
<p>{{ name1 }}</p> # 显示'Jim Green'
<p>{{ name1 }}</p>
<p>{{ name1 }}</p>
{% endwith %}
</body>

<2>使用as命名变量:
上述示例稍微调整一下:

<body>
{% with persons.0 as name1 %}
<p>{{ name1 }}</p> # 显示'Jim Green'
<p>{{ name1 }}</p>
<p>{{ name1 }}</p>
{% endwith %}
</body>

小结:具体使用哪种语法,看个人,我偏向于使用as;
使用with定义的变量,一旦范围超出'endwith',变量就失效了,这点要注意.

•spaceless标签:去除多余的空格,换行
示例:

{% spaceless %}
    <p>
        <a href="http://www.baidu.com">百度链接</a>
    </p>
{% endspaceless %}

渲染后的效果(使用谷歌浏览器的'Sources'选项,而不是用'Elements'查看):

<p><a href="http://www.baidu.com">百度链接</a></p>

● 自动转义:django默认自动转义
示例:

views

def index(request):

context={
    ......
    'info':"<a href='http://www.baidu.com'>百度链接</a>" # 注意这里的链接,只能用字符串来表示.
}
return render(request,'index.html',context=context)

html

{{ info }} # 效果:<a href='http://www.baidu.com'>百度链接</a>

源码:<a href='http://www.baidu.com'>百度链接</a> # 引号,破折号全被转义

现在,使用{% autoescape %}标签关闭/开启自动转义

html

{% autoescape off %}
    {{ info }}
{% endautoescape %}

效果:成功实现链接的操作,而不会被转义成普通字符串.

• verbatim标签:包含在里面的'变量',不再表示'变量',它的作用就是可以和别的模板引擎混合使用
也就是说,可以把别的模板引擎语言,写在里面.
示例:

{% verbatim %}
    {{ var }}
{% endverbatim %}

● url标签:反转网址,效果和view的reverse一样
示例:

html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Front index page</title>
<style>
.nav{
overflow: hidden; # <ul>标签使用样式
}
.nav li{ # <li>标签使用样式
float: left;
list-style: none;
margin: 0 20px;
}
</style>
</head>
<body>
<ul class="nav"> # 定义class属性,便于使用css样式
<li>首页</li>
<li>读书</li>
<li>电影</li>
<li>同城</li>
</ul>
</body>
</html>

views

def book(request):
return HttpResponse('读书页')

def movie(request):
return HttpResponse('电影页')

def city(request):
return HttpResponse('同城页')

urls

from django.contrib import admin
from django.urls import path
from front import views

urlpatterns = [
path('admin/', admin.site.urls),
path('',views.index),
path('book/',views.book,name='book'),
path('movie/',views.movie,name='movie'),
path('city/',views.city,name='city'),
]

启动服务,看看基本的效果,正常.
现在修改html文档,添加<a>标签链接:

<body>
<ul class="nav">
<li><a href="#">首页</a></li> # 这里href='/'也可以
<li><a href="{% url 'book' %}">读书</a></li> # 使用url标签做网址跳转
<li><a href="{% url 'movie' %}">电影</a></li>
<li><a href="{% url 'city' %}">同城</a></li>
</ul>
</body>

刷新一下,成功实现效果

• url标签接收url额外的参数示例:

views

...
def book_number(request,number):
text='The number of book_id is {}'.format(number)
return HttpResponse(text)

urls

...
path('book_detail/<number>',views.book_number,name='book_number'),

html

<body>
<ul class="nav">
<li><a href="#">首页</a></li>
<li><a href="{% url 'book' %}">读书</a></li>
<li><a href="{% url 'movie' %}">电影</a></li>
<li><a href="{% url 'city' %}">同城</a></li>
<li><a href="{% url 'book_number' number=6 %}">书籍编号</a></li> # 使用关键字参数来传递额外的值
</ul>
</body>

刷新效果,网址成功跳转

• url 查询字符串拼接(和reverse类似,也是采用拼接的方式)
示例:

views

def login(request):
keyword=request.GET.get('next')
if keyword:
text='登陆后跳转的url是{}'.format(keyword)
else:
text='next为空'
return HttpResponse(text)

urls

......
path('login/',views.login,name='login'),

html

<body>
<ul class="nav">
......
<li><a href="{% url 'book_number' number=6 %}">书籍编号</a></li>
<li><a href="{% url 'login' %}?next=">登陆</a></li> # 注意这种拼接的语法
</ul>
</body>

访问:http://127.0.0.1:8000/,点击'登陆'
跳转到:http://127.0.0.1:8000/login/?next= 网页显示'next为空'
现在给next赋值:<a href="{% url 'login' %}?next=用户的url">登陆</a>
跳转到:http://127.0.0.1:8000/login/?next=%E7%94%A8%E6%88%B7%E7%9A%84url,网页显示'登陆后跳转的url是用户的url'

复习之前的reverse()手动拼接url

def name(request):
query_string=request.GET.get('name')
if query_string:
text='Your name is {}'.format(query_string)
# 此时,若想获取当前url,只能手动拼接...
local_url=reverse('name')+'?name={}'.format(query_string) # /name/?name=JimGreen
print(local_url)
else:
text='Nothing'
return HttpResponse(text)

● DTL过滤器(函数)

• add过滤器:对传进来的值,进行'相加'或'拼接'操作
示例:

views

def index(request):
context={
'value':100 # 值为整型
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|add:200 }}</p> # 结果为300
</body>

源码:

def add(value, arg): # 接收的第一个参数是value
"""Add the arg to the value."""
try:
return int(value) + int(arg) # 优先进行整型计算
except (ValueError, TypeError):
try:
return value + arg # 否则就进行拼接
except Exception: # 如果拼接不成功,就返回空字符串
return ''

• cut过滤器:移除字符串中指定的值,类似于replace(args,' ')
示例:

views

def index(request):
context={
'value':'Jim Green',
}

html

<body>
<p>{{ value|cut:' ' }}</p> # JimGreen
</body>

• date过滤器:须传入datetime对象,再date转换成时间格式(具体的格式视需求而定)
示例:

views

from django.http import HttpResponse
from django.shortcuts import render
import datetime

def index(request):
context={
'today':datetime.datetime.now(),
}
return render(request,'index.html',context=context)

HTML

<p>{{ today|date:'Y-m-d' }}</p> # 2019-11-05

注意:datetime对象的默认形式,类似下面这样的,显然,不是我们想要的格式,故可以使用data过滤器达到想要效果格式:

from datetime import datetime
now=datetime.now()
now
datetime.datetime(2019, 12, 19, 14, 14, 30, 490242) # 类元组的格式吧...

date的其他参数,可以查阅官方文档进行修改

• default过滤器:若传入的value值为True,则返回该值,不做任何修改;若值为False,则返回default传入的值
示例:

views

def index(request):
context={
'value':'default值测试', # 若值为空list,则返回'计算为false'
}

html

<body>
<p>{{ value|default:'计算为false' }}</p> #返回 default值测试
</body>

default_if_none过滤器:仅仅只有值为None时,才渲染后面的值
示例:

views

def index(request):
context={
'value':None,
}
return render(request,'index.html',context=context)

html

<p>{{ value|default_if_none:'传入的值为None' }}</p> # 结果为:传入的值为None

• first/last过滤器:返回list,tuple,str的第一个/最后一个元素
示例:

views

def index(request):
context={
'value':['apple','pear','banana','noddle'],
}
return render(request,'index.html',context=context)

html

<p>{{ value|last }}</p> # noddle
<p>{{ value|first }}</p> # apple

• 对浮点数的位数进行限制---floatformat过滤器
示例:

views

def index(request):
context={
'value':63.8536,
}
return render(request,'index.html',context=context)

html

<p>{{ value|floatformat }}</p> # 63.9 不传参,默认只保留一个小数,四舍五入
<p>{{ value|floatformat:2 }}</p> # 63.85 保留两位小数,四舍五入

• join过滤器---对 list,str,tuple的元素进行拼接
示例:

views

def index(request):
context={
'value':[1,2,3,4]
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|join:'/' }}</p> # 1/2/3/4
</body>

• length过滤器---返回list,str,tuple的的长度(从1开始)
示例:

views

def index(request):
context={
'value':[1,2,3,4]
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|length }}</p> # 4
</body>

• lower(小写)/upper(大写)
示例:

views

def index(request):
context={
'value':'KING'
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|lower }}</p> # king
</body>

• random过滤器:随机从list,tuple,str选择一个元素
示例:

views

def index(request):
context={
'value':[1,2,3,4,5,6,7]
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|random }}</p> # 随机出现一个数字
</body>

• safe---相当于{% autoescape off %}
示例:

views

def index(request):
context={
'value':"<script>alert('Hello World')</script>"
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|safe }}</p> # 弹窗(说明js执行成功),这里若把safe省略,则会被自动转义成普通str
</body>

• slice---切片操作
示例:

views

def index(request):
context={
'value':[1,2,3,4,5,6]
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|slice:"3:5" }}</p> # [4,5] 切片从0开始
</body>

• striptags过滤器:去除value的html标签
示例:

views

def index(request):
context={
'value':"<script>alert('Hello World')</script>"
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|striptags }}</p> # alert('Hello World')

• truncatechars过滤器:如果给定的字符串长度超过了过滤器指定的长度。那么会进行切割,并且拼接三个点来作为省略号
注意:三个点也算在指定的长度里面,算三个字符
示例:

views

def index(request):
context={
'value':"北京非常欢迎你"
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|truncatechars:"5" }}</p> # 北京...
'''
解析:value长度为7,超过过滤器指定的长度5,触发切割,留3个字符给'.'号,所以只能分配两个字符给'北京'
'''
</body>

html

<body>
<p>{{ value|truncatechars:"8" }}</p> # 北京非常欢迎你
'''
解析:value长度为7,没有超过过滤器指定的长度8,没有触发切割,所以原样返回'
'''
</body>

• truncatechars_html过滤器:同理;不同的地方,它不会计算html元素
示例:

views

def index(request):

context={
    'value':"<p>北京非常欢迎你</p>"
}
return render(request,'index.html',context=context)

html

<body>
<p>{{ value|truncatechars_html:"5" }}</p> # <p>北京...</p>
</body>

● 自定义过滤器

<1>新建app并install_app

<2>app目录下,新建py包,并且一定命名为'templatetags'

<3>新建filename.py文件(例如'my_filters.py')

<4>导入注册模块,编写需要的功能
示例:

from django import template

register=template.Library()

'''
a) 自定义的函数,最多只能有两个参数
b) 第一个参数,永远是|左边的变量
'''
def join_together(value,word):
return value+' '+word

register.filter('join_together',join_together)


另一种写法---装饰器修饰

from django import template

register=template.Library()

@register.filter('join_to') # 这里若不传过滤器名称,则默认以'函数名称'作为'过滤器名称'
def join_together(value,word):
return value+' '+word

<5>view,html示例如下:

views

def index(request):
context={
'value':"Hello"
}
return render(request,'index.html',context=context)

html

{% load my_filter %} # 不能忘记加载刚才定义'my_filter.py'

<body>
<p>{{ value|join_together:'World' }}</p> # Hello World
</body>

★ 实际需求功能:有一个这样的值

时间1分钟以内---值就显示:刚刚

1m<x<60m---几分钟之前

1h<x<24h---几小时之前

1d<x<30d---几天前

x>30d---显示具体时间

my_filters.py

from django import template
from datetime import datetime

@register.filter()
def time_since(value): # value表示过去的时间
if not isinstance(value,datetime): # 对传入的值进行判断
return value
now=datetime.now() # 获取当前时间
timestamp=(now-value).total_seconds() # 获取时间差,用总秒数表示
if timestamp<60:
return '刚刚'
elif timestamp>=60 and timestamp<6060:
time=int(timestamp/60)
return '{} 分钟之前'.format(time)
elif timestamp>=60
60 and timestamp<606024:
time=int(timestamp/60/60)
return '{} 小时之前'.format(time)
elif timestamp>=606024 and timestamp<606024*30:
time=int(timestamp/60/60/24)
return '{} 天之前'.format(time)
else:
return value.strftime("Y%-m%-d%-H%-M%") # 留意这种时间格式

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容