Day 03
咕了好几天。今天的博客是跟前端相关的一些笔记。
Jinja2
flask使用jinja2来渲染一些模板,在创建项目时会自动创建template目录,里面就是用来存放需要渲染的模板文件的。如果修改了默认的模板路径,则要在初始化时指定 template_folder 。渲染的具体操作如下:
#在template文件夹下面寻找 from flask import render_template
视图函数:... return render_template('index.html') #自定义模板文件路径 Flask(__name__, template_folder='')
传递参数:
#在render_template函数中 return render_template('index.html', username=...,) #在html文件中使用双大括号引用参数 {{username}}
但是如果有许多参数要传递,一个个写死看很不方便,常用的方法是把这些参数装在一个列表里,然后把列表传过去:
context = [ 'username':... 'age':... 'country':... ] #return render_template('xxx.html',context=context) #在html中调用时 {{context.age}} 或直接采用:(常用) return render_template('xxx.html',**context) 在调用时可直接使用context中的变量名 ...
模板中使用 url_for 和之前的写法基本一样:
<a href="{{ url_for('login',id=...) }}">登录a>
对应的视图函数:
过滤器
在模板中有一个比较好用的东西叫过滤器。过滤器是通过管道符号( | )进行使用的,例如{{ name | length}}将返回name的长度。过滤器相当于一个函数,把当前变量传入过滤器,然后过滤器根据自己的功能返回相应值。
#基本语法: @app.route('/') def index(): return render_template('index.html',num=10) #html中绝对值为:{{ num|abs }}
默认过滤器(default):
#对上例扩充: @app.route('/') def index(): context = [ 'position':10 #'signature':'我的个性签名' ] return render_template('index.html',**context) #html中:个性签名:{{ siganure|default('此人很懒,什么都没留下',boolean=True) }}
如果默认函数不指定 boolean=True,则只会在找不到对象时调用默认函数,如果指定为 True,则对应的变量值为False时也会调用默认函数。比如上例中signature为None, 或空字符串、空列表、空字典等等。
可以用 or 来代替 default 函数,简写形式:{{ siganture or '此人很懒,什么都 没有留下' }}。
下面例举一些常用的过滤器:
escape或e:转义字符,会将<、|>等符号转译成html中的符号
safe:关闭自动转义
{% autoescape off %} <p>个性签名:{{ signature|escape }}p> {% endautoescape %} <p>个性签名:{{ signature|safe }}p>
format:格式化字符串,例
<p> {{ '%s %s'|format('arg1','arg2'...) }} p>
truncate(value, length=255, killwords=False):截取length长度的字符串
striptags:删除字符串中所有的html标签,并将多个空格替换为一个空格
first:返回一个序列中的第一个元素
last:返回一个序列中的最后一个元素
length:返回一个序列或者字典的长度
replace(value, old, new):将old替换为new
wordcount(s):计算字符串中单词s的个数
int,float,string,join,lower,upper...功能同python
自定义过滤器:
使用方法:
app.config['TEMPLATES_AUTO_RELOAD'] = True @app.template_filter('filter_name') def fun(value): #.... return value #在使用时:{{ article|filter_name }}
例:
#对前例扩充: from datetime import datetime @app.route('/') def index(): context = [ 'position':10 #'signature':'我的个性签名' 'creat_time':datetime.now() ] return render_template('index.html',**context) @app.template_filter('handle_time') def handle_time(time): ''' 1.如果距离现在时间间隔小于1min,显示'刚刚' 2.如果1h以内,显示'xx分钟前' 3.如果一天内,显示'xx小时前' 4.如果一个月内,显示'xx天前' 5.否则显示具体时间 ''' if isinstance(time, datetime): now = datetime.now() timestamp = (now - time).total_seconds() if timestamp < 60: return '刚刚' elif timestamp >= 60 and timestamp < 60*60: minutes = timestamp / 60 return '%s分钟前' %int(minutes) elif timestamp >= 60*60 and timestamp < 60*60*24: hours = timestamp / (60*60) return '%s小时前' %int(hours) elif timestamp >3600*24 and timestamp < 3600*24*30: days = timestamp / (3600*24) return '%s天前' %int(days) else: return time.strftime('%Y/%m/%d %H:%M') else: return time
宏
模板中的宏与函数类似,可以传递参数但是不能有返回值,可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量。
用导入的方式使用宏时,要以'templates'为绝对路径查找宏文件。
{% macro input(name="", value="", type="text") %} <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> {% endmacro %} <table> <tbody> <tr> <td>用户名:td> <td>{{ input('username') }}td> tr> <tr> <td>密码:td> <td>{{ input('password',type='password') }}td> tr> <tr> <td>用户名:td> <td>{{ input(value="提交",type='submit') }}td> tr> tbody> table>
静态文件
js,css,image等文件都可以放在static目录下,具体使用如下
<link rel="stylesheet" href="{{ url_for('static', filename="css/index.css") }}"> <script src="{{ url_for('static', filename='js/index.js') }}">script> <img src="{{ url_for('static', filename="imgs/pic.jpg") }}" alt=''>
模板继承
把一些共用的代码抽取出来当成父模板,子模版使用extends根据需求实现不同的代码
{% block block_name% } {% endblock% } {% extends 'base.html' %} {% block block_name %} ... ... {% endblock %}