一、 flask简介

背景:
首先看一下用户通过浏览器访问网站的页面信息,经过了哪些?

  • flask与http没有协议,不可以与nginx直接沟通,需要uwsgi,wsgi可以与flask通过web协议沟通,也可以与nginx沟通;
  • 当用户访问url时,通过函数返回结果给wsgi,wsgi再给nginx

Web前端—Flask、Jinja2入门

  • Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供IMAP / POP3 / SMTP服务。接收的请求量大,10K。
  • uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。http协议和nginx进行交流,WSGI协议和后端的python代码,wed框架进行交流。
  • Framework即架构,它是一个语言开发软件,提供了软件开发的框架,使开发更具工程性、简便性和稳定性。常用的就是django和falsk框架,falsk用于小项目,django用于大项目。

Flask简介
Flask是一个Web框架,就是提供一个工具库和技术来允许你构建一个Web应用程序.这个Web应用程序可以是一些Web页面,博客, wiki ,基于 Web 的日历应用或商业网站。

Flask依赖模块:
web服务网关接口(Python Web Server Gateway Interface,缩写为WSGI)

  • Werkzeug 一个WSGI工具包, 是为python语言定义的web服务器和web应用程序或框架之间的一种简单而通用的接口,其他语言也有类似的接口)
  • jinja2模板引擎。前端的操作。

Flask的优势:
Flask属于微框架( micro-framework )这一类别,微架构通常是很小的不依赖外部库的框架.
框架很轻量
更新时依赖小
专注于安全方面的bug

基于flask建立一个网站

路由:url地址的路径,路由根据用户提交的路径,判断执行什么函数

@app.route('/login/') #当用户输入网址/login/所对应的路由 

视图函数:用户输入网址对应到路由下所执行的函数

 def login():      return 'logining..'  #当用户访问登陆页面时返回logining 
from flask import Flask  # 实例化,__name__:确定flask项目所在位置 app = Flask(__name__)  #实现首页:http://访问的ip:端口/ #路由:确保访问的路径,执行哪个函数 @app.route('/')  # 路由 def index():     # 试图函数 ,给用户返回页面信息,名字不能重复     return '这是网站的首页'  @app.route('/login/') def login():     return '正在登录'  @app.route('/logout/') def logout():     return '正在登出'   if __name__ == '__main__':     #运行flak项目,默认ip和端口是127.0.0.1:5000     #如何特色化指定?host=0.0.0.0 开放本机所有的ip port=9990 端口必须是整形数     #debug=True 是否开启调试,测试环境中开启,生产环境一定要关闭     app.run(host='0.0.0.0', port=9990, debug=True)  
  • 设置动态路由
from flask import Flask, request  # 请求信息存在request  app = Flask(__name__)  """ 动态路由方式一: http://www.csdn.org/<userid> """ #路由是一个变量 @app.route('/<int:userid>/')  #接收了一个变量信息 userid def userinfo(userid):     return "查看用户%s的详细博客" %(userid)  @app.route('/welcome/<string:username>') def welcome(username):     return "欢迎访问%s用户的主页" %(username)  """ 动态路由方式二: https://movie.douban.com/top250?start=25&filter=                 有对应的 key value值 """ @app.route('/top250') def top250():     users = ['user%s' %(i) for i in range(100)]     # request 存储用户请求页面的所有头部信息     print('客户端的用户代理:',request.user_agent)     print('请求页面的头部信息:',request.headers)     print('客户端ip:',request.remote_addr)     print('客户端请求的参数详细信息:',request.args)  #字典对象存储     print('客户端http请求的方法:',request.method)  # http请求方法 get:会在地址栏显示,不安全,有大小限制 opst     # 获取用户请求的URL地址里的key对应的value值     start = int(request.args.get('start'))  #start对应value值为字符串类型,需要转为int型才能和int相加     user = request.args.get('user')     # return 'top 250 显示数据:%s条 用户名:%s' %(start,user)     import json     return json.dumps(users[start:start+10])  # users[start:start+10] 是一个列表,返回一个字符串内容  if __name__ == '__main__':     app.run()  

二、http请求方法的实现

1、 http请求常见的方式:GET POST

  • (1) url可见性:
    get: 参数url可见
    post: 参数不可见

  • (2) 数据传输:
    get: 通过拼接url进行传递参数
    post: 通过body体传输参数

  • (3) 缓存性:
    get请求是可以缓存的
    post请求不可以缓存

  • (4) 后退页面的反应:
    get请求页面后退时,不产生影响
    post请求页面后退时,会重新提交请求

  • (5) 传输数据的大小:
    get一般传输数据大小不超过2-4k(根据浏览器不同,限制不一样,但相差不大)
    post请求传输数据可以无限大

  • (6) 安全性:原则上
    get安全性较低
    post安全性较高

2、 模板渲染

例如: hello {{name}} 一个模板,取决于用户给返回的值
若用户返回的信息为:name = westos
就将name=westos填入 —> hello westos
flask和django都配备了Jinja2模板引擎,可以使用 render_template() 方法来渲染模板

3、 重定向和错误(redirect, error)

  • 使用redirect()函数把用户重定向到其他地方
  • 使用abort()函数,放弃请求并返回错误代码
    http状态码:404 200 304 302 500
    4开头 客户端错误
    5开头 服务端错误

4、get方法实现用户登录验证

 from flask import Flask, render_template, request, redirect  app = Flask(__name__) @app.route('/') def index():     return "<h1>主页</h1>"  @app.route('/login/') def login():     """     一般情况下,不会直接把html文件内容直接返回,     而是将html文件保存到当前的templates目录中     通过render_template方法调用;     默认情况下,flask在程序文件夹中的templates子文件夹中寻找模板     """     return render_template('login.html')  # 返回了login.html,去login.html里看,用户输入了登录信息后,提交到action="/login2/  login2路由中 # 再通过login2函数来判断用户名和密码,正确就进入主页,否则重新登陆   # 处理登录逻辑,判断用户名和密码 @app.route('/login2/') def login2():     #获取用户输入的用户名     username = request.args.get('username', None)     password = request.args.get('password', None)     # 逻辑处理,判断用户名和密码是否正确     if username == 'root' and password == 'root':         #重定向到指定路由         #如果登录成功,进入主页         return redirect('/')     else:         #return '登录失败'         #如果登录失败,重定向到登录界面,重新登录         return redirect('/login/')   if __name__ == '__main__':     app.run()  

templates目录中的login.html文件:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title> </head> <body>  <h1>用户登录</h1>  <form action="/login2/" method="get">      <input type="text" name="username" placeholder="username"><br/>     <input type="password" name="password" placeholder="password"><br/>     <input type="submit" value="登录">  </form>  </body> </html>  

Web前端—Flask、Jinja2入门

5、登陆验证之HTTP请求方法POST实现

 from flask import Flask, render_template, request, redirect  app = Flask(__name__) @app.route('/') def index():     return "<h1>主页</h1>"  # 默认路由只支持get方法,如何指定为post方法: @app.route('/login/', methods=['GET', 'POST']) def login():     """      1. 用户通过get方法访问网址:http://xxxx/login  ,返回登录的html页面,               2. 返回了html页面,用户填写信息         根据 <form action="/login/" method="post"> 提交到login,方法是post      3. 执行post提交的逻辑      """     if request.method == 'POST': #此处要大写         # post请求提交的数据如何获取?   request.form.get;  get请求如何获取:request.args.get         # post提交的数据是放在了一个表单里         print(request.form)         username = request.form.get('username', None)         password = request.form.get('password', None)          if username == 'root' and password == 'root':             # 如果登录成功,进入主页,重定向             return redirect('/')         else:             # render_template()模板渲染,给html传递变量,传的是errMessages             return render_template('login.html',errMessages="用户名或者密码错误")      else: # get提交方法执行的操作         return render_template('login.html')  if __name__ == '__main__':     app.run()  

templates目录中的login.html文件:注意判断提交方法时必须大写

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title>  </head> <body>  <h1>用户登录</h1>  <form action="/login/"  method="POST"> #此处要大写     <input type="text" name="username" placeholder="用户名">     <input type="password" name="passwd" placeholder="密码"> <br/>     <input type="submit" value="登录">  </form> <!--errmessages是一个变量,通过flask传入这个变量,就会显示这个信息--> <p style="color: red">{{errMessages}}</p> </body> </html> 

Web前端—Flask、Jinja2入门

6、自定义错误页面

为什么要自定义错误页面?
如果在浏览器的地址栏中输入了不可用的路由,那么会显示一个状态码为404的错误页面
这个页面太难看

如何自定义错误页面?
像常规路由一样,flask允许程序使用基于模板的自定义错误页面 errorhandler()
最常见的错误代码有两个:
404:用户端请求位置页面或路由时显示
500:有未处理的异常时显示

from flask import Flask, render_template  app = Flask(__name__)  @app.route('/welcome/') def welcome():     return render_template('welcome.html')  @app.errorhandler(404) def page_not_found(e):     return render_template('404.html'),404  @app.errorhandler(500) def internal_server_error(e):     return render_template('500.html'),500  if __name__ == '__main__':     app.run()  

templates目录中的404.html文件:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title> </head> <body>  <h1 style="color: green">你寻找的网站迷路了</h1>  </body> </html>  

templates目录中的500.html文件:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title> </head> <body>  <h1 style="color: green">请耐心等待,稍后再试</h1>  </body> </html>  

Web前端—Flask、Jinja2入门
7、flask日志记录:如果一味的用print()函数打印比较乱,这里可以写到flask日志里面,app访问有问题时存入日志中

静态文件存储位置:
在开发过程中,Flask静态文件位于应用的/static目录中
调用方式:
静态文件的位置是:static/style.css
{{%20url_for(‘static’,%20filename%20=%20‘style.css’)}}

  • 格式化中的常用参数如下:

Web前端—Flask、Jinja2入门

from flask import Flask import logging  app = Flask(__name__)  # 日志系统配置, 设置文件存放位置;  当前路径 handler = logging.FileHandler('app.log', encoding='UTF-8') # 设置日志文件存储格式 logging_format = logging.Formatter(             '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s') # 将日志文件处理对象和日志格式绑定, handler.setFormatter(logging_format) # 设置日志级别 handler.setLevel('DEBUG') # 将日志格式和app绑定; app.logger.addHandler(handler)   @app.route('/') def index():     app.logger.debug('hello')     app.logger.error('error')     app.logger.exception('exception')     app.logger.info('hello')     return  'index'  if __name__ == '__main__':     app.run(debug=True, port=8000)  

当前目录下出现日志内容:
运行程序,访问页面,然后查看app.log日志:
没有显示debug是因为,只显示设置的日志级别以上的日志

2020-03-05 18:59:39,897 - ERROR - Flask.py - index - 91 - error 2020-03-05 18:59:39,897 - ERROR - Flask.py - index - 92 - exception NoneType: None 

三、消息闪现

1、什么是消息闪现?

消息闪现就是只展示一次的数据 / 参数
Flask提供了一个非常简单的方法来使用闪现系统向用户反馈信息。
闪现系统使得在一个请求结束的时候记录一个信息,然后仅仅在下一个请求中访问这个数据
Flask消息闪现可以给用户更好的体验

2.应用场景

  • 上传图片代码,加入消息闪现功能

  • 进入首页只刷一次的广告

  • 用户登录成功的闪现信息

  • 用户登录失败的闪现信息

  • 用户注册成功的闪现信息

  • 用户注册失败的闪现信息

3.实现步骤

  • 引入一个函数flash,用于存储展示的信息
from flask import flash  
  • 使用flash保存,实际上是暂时帮我们保存在session里面存储时需要加密
app.config['SECRET_KEY'] = 'westos'  # 加密盐 
  • Flask后台中存储闪现信息
flash('要展示的闪现信息') 
  • 前端页面获取闪现信息
{{ get_flashed_messages() }} 

四、案例:基于GET和POST方法实现用户登陆校验

此案例实现了已知用户root和密码root可以登陆成功,并且没有用户名时可以注册来登录的功能。

新建一个Flask项目,自动返回以下目录:

  • app.py:主函数
  • static:静态文件,存储比如css文件、js文件、图片等
  • templates:模板,存储html代码

在html文件中,外联法调用css文件时,动态获取css文件有两种方法:
(1) <link href="../static/css/login.css" rel=“stylesheet” type=“text/css” media=“all” />
(2) <link href="{{%20url_for(‘static’,%20filename%20=%20‘style.css’)}}" rel=“stylesheet” type=“text/css” media=“all” />
{{%20url_for(‘static’,%20filename%20=%20‘style.css’)}} // 根据提供的信息生成一个静态的url

案例代码如下:
app.py文件:

from flask import Flask, request, render_template, redirect, session, flash  app = Flask(__name__) app.config['SECRET_KEY'] = 'westos'  # 加密盐  users = [{'username':'root', 'password':'root'}]  #会话:session #缓存:cookie  # 主页 @app.route('/') def hello_world():     return render_template('index.html')  # 登录页面 @app.route('/login/',methods=['GET','POST']) def login():     if request.method == 'GET':         return  render_template('login.html')     else:         # 获取POST提交的数据         username = request.form.get('username')         password = request.form.get('password')         for user in users:             if user['username'] == username and user['password'] == password:                 #加入到会话,存储用户的登录信息,可以认为是字典对象                 session['usernme'] = username                 #print(session)                 flash('登录成功')    # 返回的是一个列表                 return redirect('/')             else:                 flash('登录失败')                 return render_template('login.html', erromessage = "登录失败" )  # 登出页面 @app.route('/logout/') def logout():     #将session中的用户信息删除     session.pop('username')     flash('注销成功')     return redirect('/login/')  # 注册页面 @app.route('/register/', methods=['GET','POST']) def register():     """     1. GET方法:  直接返回注册页面     2. POST方法: 注册用户                 注册的用户名是否已经存在,如果存在,重新注册,                 如果不存在,存储用户名和密码到数据库中     """     if request.method == 'GET':         return render_template('register.html')     else:         username = request.form.get('username')         password = request.form.get('password')         for user in users:             # 注册的用户名是否已经存在,如果存在,重新注册,             if user['username'] == username:                 flash('注册失败,用户名已经存在')                 return redirect('/register/')             else:                 #如果不存在,存储用户名和密码到数据库中                 users.append(dict(username=username, password=password))                 flash('用户注册成功,请登录')                 return redirect('/login/')  f __name__ == '__main__':     app.run()  

index.html

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title> </head> <body>  <p style="color: red">{{ get_flashed_messages() }}</p> <!--获取缓存中的用户名信息 : session,request,g,get_flashed_messages()可以直接从前台获取后台信息--> <p style="font-size: 12px">用户{{ session.username }}登录成功</p> <p style="color: red">{{ get_flashed_messages() }}</p> <hr> <h1 style="color: green">首页</h1><br>  </body> </html>  

login.html

{#这是下载的一个比较好看html登陆界面#}  <!DOCTYPE html> <html> <head> <title>CSS3动态背景登录页面</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />   <link href="../static/css/login.css" rel="stylesheet" type="text/css" media="all" /> {#<link `href="{{%20url_for(‘static’,%20filename%20=%20‘style.css’)}}"` rel="stylesheet" type="text/css" media="all" />)#}    #动态获取css文件的两种方法  </head> <body>     <!-- main -->    <div class="main-w3layouts wrapper">       <div class="main-agileinfo">          <div class="agileits-top">              <form action="/login/" method="post">                <input class="text" type="text" name="username" placeholder="用户名" required="">                <input class="text" type="password" name="password" placeholder="密码" required="">                <div class="wthree-text">                    <ul>                       <li>                         <label class="anim">                            <input type="checkbox" class="checkbox" required="">                            <span> 记住 ?</span>                          </label>                       </li>                      <li><a href="#">忘记密码 ?</a> </li>                   </ul>                   <div class="clear"> </div>                </div>                   <input type="submit" value="登录">             </form>             <p>创建一个账号? <a href="/register/"> 立即注册!</a></p>             <p style="color: red">{{ get_flashed_messages() }}</p>          </div>         </div>        <!-- copyright -->       <div class="w3copyright-agile">          <p>© 2017 All rights Reserved</p>       </div>       <!-- //copyright -->       <ul class="w3lsg-bubbles">          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>       </ul>    </div>     <!-- //main -->      </body> </html>  

register.html

{#这是下载的一个比较好看html登陆界面#}  <!DOCTYPE html> <html> <head> <title>CSS3动态背景登录页面</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />   <link href="../static/css/login.css" rel="stylesheet" type="text/css" media="all" />  </head> <body>     <!-- main -->    <div class="main-w3layouts wrapper">       <div class="main-agileinfo">          <div class="agileits-top">              <form action="/register/" method="post">             {#                    required="" :指的是用户名不能为空#}                <input class="text" type="text" name="username" placeholder="用户名" required="">                <input class="text" type="password" name="password" placeholder="密码" required="">                <div class="wthree-text">                    <ul>  {#                   <li>#} {#                      <label class="anim">#} {#                         <input type="checkbox" class="checkbox" required="">#} {#                         <span> 记住 ?</span> #} {#                      </label> #} {#                   </li>#}                      <li><a href="#">忘记密码 ?</a> </li>                   </ul>                   <div class="clear"> </div>                </div>                   <input type="submit" value="注册">             </form>             <p>已有账号? <a href="login"> 立即登陆!</a></p>          </div>         </div>        <!-- copyright -->       <div class="w3copyright-agile">          <p>© 2020西部开源</p>       </div>       <!-- //copyright -->       <ul class="w3lsg-bubbles">          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>          <li></li>       </ul>    </div>     <!-- //main -->      </body> </html>   

五、Jinja2模板引擎

1、什么是Jinja2模板引擎
Jinja2是一个现代的,设计者友好的,仿照Django模板的python模板语言。
它速度快,被广泛使用,并且提供了可选的模板执行环境保证安全。

  • python的Web开发中,业务逻辑(实质就是试图函数的内容)和页面逻辑(html文件)是分开的, 使得代码的可读性增强,代码容易理解和维护
  • 模板渲染:在html文件中,通过动态赋值,将重新翻译好的html文件(模板引擎生效)返回给用户的过程
  • 其他的模板引擎:Mako,Template,Jinja2
  • flask中默认的模板引擎是Jinja2

2、Jinja2语法
(1)变量显示语法:

{{ 变量名 / 函数调用 }}  {{name}}  #变量名 {{url_for()}}  #函数 {{get_flashed_,essage()}}  #函数  

(2)变量内置过滤器:
类似于python中的一些方法
完整的过滤器查看位置:http://jinja.pocoo.org/docs/templates/#builtin-filters
常用的过滤器:
safe 渲染值时不转义
capitalize 把值的首字母转换成大写,其他字母转换成小写
lower 把值转换成小写
upper 把值转换成大写
title 把值中每个单词的首字母都转换成大写
trim 把值的首尾空格去掉
striptags 渲染之前把值中所有的html标签都删掉

 from flask import Flask, render_template  app = Flask(__name__)  @app.route('/') def index():     text= """     <h1>hello world</h1>     """     return render_template('jinja2.html', text=text)  if __name__ == '__main__':     app.run()  

jinja2.html:

 <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title> </head> <body> <!--safe过滤器,展示原本的html,不将它进行转义--> {{ text | safe }} <!--把值中所有的html标签都删掉,只展示文本--> {{ text | striptags }}  </body> </html>  

{{ text }}结果:
Web前端—Flask、Jinja2入门
Web前端—Flask、Jinja2入门

(3)如何自定义过滤器:

for循环

{% for i in li %}    xxxx {% endfor %}  

例如:

{% for user in users %}  <tr>     <td>{{ user.username }}</td>     <td>{{ user.password }}</td> </tr> {% endfor %}  

if语句

{% if 条件 %}    xxxx {% elif 条件 %}    xxxx {% else %}    xxxx {% endif %}  

例如:

<!--如果用户登录,显示注销--> <!--如果没有登录,显示登录和注册 --> <!--如何判断是否登录:session.get('username')--> {% if session.get('username')%}     <li><a href="logout">注销</a>/li> {% else %}     <li><a href="login">登录</a>/li>     <li><a href="register">注册</a>/li> {% endif %} 

(4)宏操作
可以理解为函数
如何定义宏:

相当于python中定义函数,利用关键字macro

{ % macro 宏名称(参数) %} xxxx {% endmacro %}  

如何调用宏:

{{ 宏名称() }} 
{# 声明jinjn2的宏 #} {% macro fun(id) %}     <h1>hello {{ id }}</h1> {% endmacro %} {#调用宏#} {{ fun(1) }} {{ fun(2) }} </body> </html> 

(5)include包含操作
直接包含,将一个html文件放到另一个html文件里

{% include "文件名.html" %} 

run.py

from flask  import  Flask, render_template  app = Flask(__name__) @app.route('/') def index():     return  render_template('index.html')  if __name__ == '__main__':     app.run(port=5002)  

index.html

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title>     <style>         .left{             width: 20%;             border: 1px solid red;             float: left;         }         .right{             width: 79%;             border: 1px solid green;             float: left;         }     </style> </head> <body> <div class="left">     { % include 'left.html' % } </div> <div class="right">    body </div>  </body> </html>  

left.html文件

<ul>     <li>新闻</li>     <li>财经</li>     <li>八卦</li> </ul>  

Web前端—Flask、Jinja2入门
(6)模板继承
一般网站的导航栏和底部不会变化,为了避免重复编写导航栏信息

就是将相同的部分抽象出来,将不同的内容填充进去
如何定义模板:block

相当于挖了个洞,将来要将不同的内容填充进去

{% block 名称 %} {% endblock %}  

模板文件:jinja2_base.html
其中{% block title %}和{% block body %}是要填充的部分

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>{% block title %} {% endblock %}</title> </head> <body>  <div style="width: 100px; height: 200px">这里是导航栏</div> {% block body %} {% endblock %} <div style="width: 100px; height: 200px">这里是底部</div>  </body> </html>  

如何继承:extends

{% extends '模板文件.html' %} {% block 名称 %} 要填充的内容 {% endblock %}  

jinja2.html:

{ % extends 'jinja2_base.html' %}  { % block title %}主页 { % endblock %}  { % block body %}  # 声明jinjn2的宏 #} { % macro fun(id) %} < h1 > hello {{id}} < / h1 > { % endmacro %} {  # 调用宏#}     {{fun(1)}} {{fun(2)}}  { % endblock %}  

Web前端—Flask、Jinja2入门

案例:jinja2模板引擎(include包含和模板继承)

每个页面分为三部分
导航栏 (内容相同)
左边(内容相同)
右边(内容不同)
所以,写一个base.html模板,包含所有页面相同的html内容
在每个页面的html文件中,继承base.html,添加各自的内容,并插入左边html
左边的模块是一个单独的html文件,插入各个页面的html中即可,修改起来比较方便
run.py

 from flask  import  Flask, render_template  app = Flask(__name__) @app.route('/') def index():     return  render_template('index.html')  @app.route('/bbs/') def bbs():     return  render_template('bbs.html')   @app.route('/blog/') def blog():     return  render_template('blog.html') if __name__ == '__main__':     app.run(port=5002)  

base.html

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>{% block title %} {% endblock %}</title>     <style>         .nav{             width: 100%;             height: 50px;             border: 1px solid red;         }         .left{             width: 20%;             border: 1px solid red;             float: left;             height: 100px;         }          .right{             width: 79%;              border: 1px solid green;             float: left;             height: 100px;         }     </style> </head> <body>  <div class="nav">     导航栏     <button>登录</button>     <button>注册</button> </div>   <div class="left">     {% include 'left.html' %}  </div>  <div class="right">     {% block body %}      {% endblock %} </div>  </body> </html>  

index.html

{% extends 'base.html' %}  {% block title %}  主页 {% endblock %} {% block body %} <h1>index</h1>  {% endblock %}  

bbs.html

{% extends 'base.html' %}  {% block title %} 论坛 {% endblock %}  {% block body %} <h1>bbs</h1> {% endblock %}  

blog.html

{% extends 'base.html' %} {% block title %}  博客 {% endblock %}  {% block body %} <h1>blog</h1>  {% endblock %}  

left.html

<ul>     <li>新闻</li>     <li>财经</li>     <li>八卦</li> </ul>  

访问主页:
Web前端—Flask、Jinja2入门
访问blog:
Web前端—Flask、Jinja2入门
访问bbs:
Web前端—Flask、Jinja2入门

  • 版权声明:文章来源于网络采集,版权归原创者所有,均已注明来源,如未注明可能来源未知,如有侵权请联系管理员删除。

发表回复

后才能评论