flask与模板的应用

抖音自从16年上线以来,几乎所有的毒鸡汤都在说:

千万别刷抖音,它会把你毁掉的!

然而我却想说,抖音不是在摧毁,抖音只是在迎合。

它不仅仅在迎合女性,它是迎合人性。

人性本身就是贪婪、好色、懒惰、肤浅、愚蠢……

而学习、努力、自律是对欲望的克制、是辛苦的,是反人性的。

是只有少数人通过学习自律,慢慢克服和摆脱自己人性的弱点,也只有少数人是清醒的。

我们在抖音上大多数看到的短视频,是大多数人通过贪婪、好色、肤浅、愚蠢的人性,做出的投票,反映出人性本身真实的想法和愿望。

抖音也只是通过算法,把这里大多数人都喜欢看到、并且支持和认同的观点和声音,自动筛选和呈现出来,让我们看见。

一、模板

想要开发出易于维护的应用,关键在于编写形式简洁且结构良好的代码。到目前为止你看到的示例都还过于简单,无法说明这一点,但Flask视图函数的两个完全独立的作用却被融合到了一起,这就产生了一个问题。

视图函数的作用很明确,即生成请求的响应,如别再和我说你不会用flask编写简单应用了!示例中所示。对于简单的请求来说,这就足够了。但是在很多情况下,请求会改变应用的状态,而这种变化就发生在视图函数中。

以用户在网站上注册新用户为例,用户在表单中输入电子邮件和密码,然后点击提交按钮。服务器接收到包含用户数据的请求,然后flask把请求分派给处理注册请求的视图函数。这个视图函数需要访问数据库,添加新用户,然后生成响应返回给浏览器,指明操作成功还是失败。这两个过程分别称为业务逻辑表现逻辑

把业务逻辑和表现逻辑混在一起会导致代码难以理解和维护,假设要为一个大型表格构建HTML代码,表格中的数据由数据库中读取的数据以及必要的HTML字符串连接在一起,把表现逻辑迁移到模板中可以提升应用的维护性。

模板是包含响应文本的文件,其中包含占位变量表示的动态部分,其具体值只在请求上下文中才能知道。使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染。为了渲染模板,flask使用名为Jinja2的强大模板。

1.1 Jinja2模板引擎

形式最简单的Jinja2模板是一个响应文本的文件。

在templates文件夹下创建HTML文件

示例1-1 templates/index.html

<h1>Hello world</h1>

示例1-2 templates/user.html

<h1>Hello,{{name}}</h1>

1.1.1 渲染模板

默认情况下flask在应用目录中的templates子目录中寻找模板。

示例1-3 hello.py 渲染模板

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/user/<name>')
def user(name):
    return render_template('user.html', name=name)

flask提供**render_template()**函数把jinja2模板引擎集成到应用中,这个函数第一个参数是模板的文件名,随后的参数都是键——值对(关键字参数),表示模板变量对应的具体值。在这段代码中,第二个模板中收到一个名为name的变量。

示例1-4 hello.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    # 类
    class Person(object):
        name = u'p17bdw'
        age = 18

    person1 = Person()
    context = {
        'username''c17bdw',
        'gender'u'男',
        'age'17,
        'person': person1,
        'websites': {
            'baidu''www.baidu.com',
            'google''www.google.com'
        }
    }
    return render_template('index.html', **context)

1.1.2 变量

在模板中使用{{name}}结构表示一个变量,这是一种特殊的占位符,告诉模板这个值从渲染模板时使用的数据中获取。

示例1-3中,通过对context的封装,就可以在模板中通过变量访问到context里面的数据。

示例1-5 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>这个是HTML中出现的文字</h1>

<p>用户名:{{username}}</p>
<p>性别:{{gender}}</p>
<p>年龄:{{age}}</p>

<hr >
<p>名字:{{person.name}}</p>
<p>年龄:{{person.age}}</p>

<hr >
<p>百度:{{websites['baidu']}}</p>
<p>谷歌:{{websites['google']}}</p>

</body>
</html>

从上面的代码示例中不难发现Jinja2能识别所有的变量类型,甚至是复杂的类型,例如列表、字典和对象。

1.1.3 控制结构

Jinja2提供了多种控制结构可以用来改变模板的渲染过程。

示例 1-6 if_statement.py

# 输入http://127.0.0.1:5000/1/ 为登录状态,否则为未登录状态
from flask import Flask, render_template


app = Flask(__name__)


@app.route('/<is_login>/')
def index(is_login):
    if is_login == '1':
        user = {
            'username'u'啃书君',
            'age'18
        }
        return render_template('index.html', user=user)
    else:
        return render_template('index.html')

示例1-7 index.html

<!DOCTYPE html>
<html lang="zh">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title></title>
</head>
<body>
 <!-- 当user存在,并age大于15时,页面渲染的效果 -->
 {% if user and user['age'] > 15 %}
  <a href="#">{{user['username']}}</a>
  <a href="#">注销</a>
 
 {% else %}
  <a href="#">登录</a>
  <a href="#">注册</a>
 {% endif %}
</body>
</html>

上述示例代码的运行差异是登录状态与未登录状态的区别。

1.1.4 循环结构

示例 1-8 for_statement.py

from flask import Flask, render_template

app = Flask(__name__)
# for遍历字典
@app.route('/')
def index():
    books = [
        {
            'name''西游记',
            'author''吴承恩',
            'price'109
        },
        {
            'name''红楼梦',
            'author''曹雪芹',
            'price'200
        },
        {
            'name''三国演义',
            'author''罗贯中',
            'price'120
        },
        {
            'name''水浒传',
            'author''施耐庵',
            'price'130
        }
    ]

    return render_template('index.html', books=books)

在这部分,需要注意最后一行代码,第一个books是等一下交给和HTML代码去访问的,第二个books是在代码中定义的books

示例1-9 index.html

<!DOCTYPE html>
<html lang="zh">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title></title>
</head>
<body>
 <table border="1">
  <thead>
   <th>书名</th>
   <th>作者</th>
   <th>价格</th>
  </thead>
 </table>
 <tbody>
  {% for book in books %}
   <tr>
    <td>{{book.name}}</td>
    <td>{{book.author}}</td>
    <td>{{book.price}}</td>
   </tr>
  {% endfor %}
 </tbody>
</body>
</html>

1.1.5 过滤器

1、介绍和用法

  • 介绍:过滤器可以处理变量,把原始的变量经过处理后再展示出来。作用的对象是变量。
  • 语法:

{ avatardefault(‘xxx’)}

2、default过滤器:如果当前变量不存在,这时候可以指定默认值。

3、length过滤器:求列表、字符串、字典、元组的长度。

4、常用过滤器介绍

过滤器 功能
abs(value) 返回一个绝对值
first(value) 返回序列的第一个值,示例:names|first
last(value) 返回序列的最后一个值,示例:names|last
length(value) 返回一个序列的长度,示例:names|length
join(value, d=’u’) 将一个序列用d这个参数拼接成字符串

我只介绍上面这几个函数,flask可以识别所有的函数。

看下面的示例:

index.html

<!DOCTYPE html>
<html lang="zh">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>过滤器</title>
</head>
<body>
 
 <p>评论数:({{comments|length}})</p>
 {% for comment in comments %}
  <li>
   <a href="#">{{comment.user}}</a>
   <p>{{comment.content}}</p>
  </li>
</body>
</html>  

filter_dmeo.py

from flask import Flask,render_template

app = Flask(__name__)


@app.route('/comments')
def index():
    comments = [
        {
            'user''张三',
            'content''up加油'
        },
        {
            'user''李四',
            'content''undo'
        }
    ]
    return render_template('index.html', comments=comments)

1.1.6 继承与block

为了避免代码的复用,可以使用模板继承,这个类似于Python代码中的继承。

1、继承的作用和语法

  • 作用:可以把公共的代码放入父模板中,避免每个模板写同样的代码。
  • 语法:{% extend base.html %}

2、block的实现

  • 作用:可以让子模板实现自己的需求。父模板需要提前定义好
  • 注意点:子模板的代码必须放在block块中。

base.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>{% block title %}{% endblock %}</title>

 <style type="text/CSS">
  .nav {
   background#3a3a3a;
   height65px;

  }
  ul {
   overflow: hidden;

  }

  ul li {
   float: left;
   list-style: none;
   padding0 10px;
   line-height65px;

  }

  ul li a {
   color#fff
  }
 
</style>
 {% block head %}{% endblock %}
</head>
<body>

 <div class="nav">
  <ul>
   <li><a href="#">首页</a></li>
   <li><a href="/login">发布问答</a></li>
  </ul>
 </div>
 {% block main %}{% endblock %}


 
</body>
</html>

index.html

{% extends base.html %}

{% block head %}
<style type="text/css">
 
</style>

<link rel="stylesheet" type="text/css" href="">
<script type="text/Javascript"></script>

{% endblock %}

{% block title %}
首页
{% endblock %}

{% block main %}
这是首页
{% endblock %}

login.html

{% extends "base.html" %}

{% block title %}
登录界面
{% endblock % }

{% block main %}
这个是登录界面
{% endblock %}

app.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
 return render_template('index.html')

@app.route('/login/')
def login():
 return render_template('login.html')

上面的就是继承的案例,把公共的代码放入base.html(父类),在该文件中需要使用block和endblock进行占位,而后在子类中进行替换,即可使用。

2.1 使用Flask-Bootstrap集成Bootstrap

bootstrap是Twitter开发的开源框架,它提供的用户组件可以创建一个简洁的web页面。而且兼容现代桌面和移动平台的web浏览器。

我们现在要使用的是flask-bootstrap拓展,可以使用pip安装

pip install flask-bootstrap

接下来,看一下bootstrap的使用方法。

user.html

{% extends "bootstrap/base.html" %}

{% block title %}flask{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
 
 <div class="container">
   <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="/">flasky</a>
    </div>
 </div>

  <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="/">Home</a></li>
      </ul>
    </div><!-- /.navbar-collapse -->
</div>
{% endblock %}

{% block content %}
<div class="container">
 <div class="page-header">
  <h1>Hello,{{name}}</h1>
 </div>
</div>
{% endblock %}

hello.py

from flask import Flask, render_template
from flask_bootstrap import Bootstrap


app = Flask(__name__)
bootstrap = Bootstrap(app)

@app.route('/user/<name>/')
def user(name):
    return render_template('user.html', name=name)

@app.route('/'):
def index():
 return '<h1>Hello world</h1>'

2.2 链接

任何具有多个路由的应用都需要可以连接不同页面的链接。例如导航栏。

在模板中直接编写简单路由的URL并不难,但是对于包含可变部分的动态路由、在模板中构建URL就很困难了。

为了避免这些问题,Flask提供了url_for( )辅助函数,它使URL映射中保存的信息生成URL。

url_for( )函数最简单的用法是以视图函数名作为参数,返回对应的URL。

url_for()生成动态url时,将动态部分作为关键字参数传入。

使用方法:

在模板引擎中的的换成url_for('index')即可。

2.3 静态文件

web应用不仅由Python源码与模板组成,还有很多的静态文件,例如,css、图片和js文件。

在默认设置下,Flask在应用根目录中名为static的子目录中寻找静态文件,如果需要的话,可以在static文件夹下添加子文件

使用方法:

url_for('static', filename='css/style.css')

最后

聪明人知道世界很大,他们所知甚少。

愿意包容不同的人和意见,有能力学习和改变自己,不断通过输入进步的信息,来更新自己的观念。

点个【在看】,让我们一起在人云亦云的网络时代,做个清醒的聪明人,而不是被大数据操控,却浑然不知的笨蛋。

我是啃书君,一个专注于学习的人。你懂的越多,你不懂的越多,更多精彩内容我们下期再见!


原文始发于微信公众号(小志Codings):flask与模板的应用

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/40046.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!