Flask学习笔记(3)

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 和之前的写法基本一样:

<!--index页面中的登录按钮-->
<a href="{{ url_for('login',id=...) }}">登录</a>

对应的视图函数:

@app.route('/account/login/<id>')
def login(id):

  return render_template('login.html')

过滤器

在模板中有一个比较好用的东西叫过滤器。过滤器是通过管道符号( | )进行使用的,例如{{ name | length}}将返回name的长度。过滤器相当于一个函数,把当前变量传入过滤器,然后过滤器根据自己的功能返回相应值。

#基本语法:
@app.route('/')
def index():
    return render_template('index.html',num=10)
#html中
<p>绝对值为:{{ num|abs }}</p>

默认过滤器(default):

#对上例扩充:
@app.route('/')
def index():
    context = [
        'position':10
        #'signature':'我的个性签名'
    ]
    return render_template('index.html',**context)
#html中:
<p>个性签名:{{ siganure|default('此人很懒,什么都没留下',boolean=True) }}</p>

如果默认函数不指定 boolean=True,则只会在找不到对象时调用默认函数,如果指定为 True,则对应的变量值为False时也会调用默认函数。比如上例中signature为None, 或空字符串、空列表、空字典等等。

可以用 or 来代替 default 函数,简写形式:{{  siganture or '此人很懒,什么都 没有留下' }}。

下面例举一些常用的过滤器:

escape或e:转义字符,会将<、|>等符号转译成html中的符号

safe:关闭自动转义

{% autoescape off %} <!--Jinja2模板默认开启escape-->
    <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
#在使用时:
<p>{{ article|filter_name }}</p>

例:

#对前例扩充:
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 %}
<!--from 'path' import 'xxx' as xxx with context-->
<!--使用-->
<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目录下,具体使用如下

<!--.css-->
<link rel="stylesheet" href="{{ url_for('static', filename="css/index.css") }}"><!--js-->
<script src="{{ url_for('static', filename='js/index.js') }}"></script><!--image-->
<img src="{{ url_for('static', filename="imgs/pic.jpg") }}" alt=''>

模板继承

把一些共用的代码抽取出来当成父模板,子模版使用extends根据需求实现不同的代码

<!--父模板中-->
{% block block_name% }
{% endblock% }
​
<!--子模版中-->
{% extends 'base.html' %}
{% block block_name %}
...<!--通过{{ super() }}使用父模板的代码-->
...<!--通过{{ self.block_name }}使用其它block的代码-->
{% endblock %}

 

猜你喜欢

转载自www.cnblogs.com/Ishtarin/p/12264209.html