python在网络方面的应用非常广泛,这里我们关注一下网站服务器及web开发部分。python几行代码就可以搭建一个web服务器,然后使用python语言来开发后台服务。之前的文章我对web服务做了较为详细的介绍,这个服务主要包括http的各种类型请求,如get、post等常规请求。对于web开发,不同页面之间的跳转、数据传输通信、网页存储、缓存等是基础知识,如果采用原生python来写估计难度还是很大的,所以感谢前人栽树,有了一些成熟的框架模块,我们再来使用时就非常方便。当然至于python用于web服务的性能如何,这里我们不做讨论。在web开发框架部分,较为知名的包括django、flask等框架。
 
Flask是一个用Python编写的Web应用程序框架。它由Armin Ronacher开发,他领导一个名为Pocco的国际Python爱好者团队。Flask基于Werkzeug WSGI工具包和Jinja2模板引擎。两者都是Pocco项目。对于Flask框架的应用基础和使用经验,网络上有许多可以文章可以参考。我们以上手实践为主,来使用flask搭建一个较为简单的web网站。
 
(1)flask安装
 
flask是第一个第三方库。与其他模块一样,安装时可以直接使用python的pip命令实现。
 
首先要保证安装好python的开发环境,建议安装python3。笔者安装的版本是3.9
 
开发IDE使用的是vscode,当然你也可以使用pycharm、idea、spyder等等都可以。
 
flask的安装命令:pip install flask
 
(2)flask搭建服务器
 
flask是web开发框架,简单易学,因此用flask来搭建web服务也非常简单。
 
新建一个项目,命名为web,然后新建一个python文件,命名为main.py。在代码中输入如下代码:
 
from flask import  Flask
app=Flask(__name__)
@app.route('/')
def index():
    return 'welcome to my webpage!'
if __name__=="__main__":
    app.run(port=2020,host="127.0.0.1",debug=True)
 
这样一个flask的web项目就完成了。
 
在当前目录下,在终端termianl中输入命令:python main.py就可以运行起来了。效果如下:
 

 
不过要在return里语句加入html长串代码,显然不合适,所以需要使用flask库里的Jinja2模板引擎,调用flask模块里的render_template方法,将静态的html文件传入,同时也可以将数据传输到html文件中显示。此时我们修改一下上述案例代码,形成一个相对完善的一个demo。
 
(3)flask开发简单网站
 
到此为止,我们使用flask框架实现了一个网页的开发,还可以传输数据。但网站肯定是由多个网页构成的,多个网页之间还要实现相互链接访问。下面我们在上述基础上增加两个网页,来说明多网页开发和链接的方法。
 
蓝图是flask框架为解决项目框架搭建的工具。我们将一个网站所有的路由文件都放在main.py服务器文件中,简单的业务处理是没问题,但随着业务量需求增多,在不断扩展时将所有路由配置都放在一个文件里肯定是不行了,需要分业务来配置路由及模型,此时就可以使用flask框架提供的blueprint类来实现。案例包括首页、用户注册、新闻、产品介绍业务,由此我们可以将这几个业务分开单独各成一个路由处理文件。
 
首先在web目录下新建三个py文件,分别命名为user.py、news.py、product.py。每个文件处理对应的业务。在每个文件里都使用blueprint模块,以user.py为例,使用的方法如下:
 
 
  from flask import Blueprint, render_template, session, url_for,request 
 
 
  from werkzeug.utils import redirect 
 
 
  
 
  
  
user=Blueprint('user',__name__) #蓝图使用方法,参数里给定文件名,还可以给定url前缀 
 
 
  
 
  @user.route('/login') #使用user的路由配置 
 
 
  def loginpage(): 
 
 
     return render_template("login.html") 
 
 
  
 
  
  
@user.route('/loginProcess',methods=['POST','GET']) #使用user 的路由配置 
 
 
  def loginProcesspage(): 
 
 
     if request.method=='POST': 
 
 
        nm=request.form['nm'] 
 
 
        pwd=request.form['pwd'] 
 
 
        if nm=='wlx' and pwd=='111': 
 
 
          session['username']=nm 
 
 
          print(session['username']) 
 
 
          return redirect(url_for('index')) 
 
 
        else: 
 
 
          return 'the username or userpwd does not match!' 
 
 
 
     
 
 
  
news.py代码如下:
 
 
  from flask import Blueprint, render_template 
 
 
  import sys 
 
 
  sys.path.append("../..") 
 
 
  from dbUtil import DBUtils 
 
 
  
 
  news=Blueprint('news',__name__) #news蓝图 
 
 
 
     
 
 
  
 
  @news.route('/news') 
 
 
  def newspage(): 
 
 
     db=DBUtils('web.db') 
 
 
     sql='select * from news' 
 
 
     newslist=db.db_action(sql,1) 
 
 
     return render_template("news.html",data=newslist) 
 
 
  
 
  
  
@news.route('/news/edit') 
 
 
  def newsEditpage(): 
 
 
     return '/news/edit' 
 
 
  
product.py代码如下:
 
 
  from flask import Blueprint, render_template 
 
 
  product=Blueprint('product',__name__) 
 
 
  
 
  
  
@product.route('/product') 
 
 
  def productpage(): 
 
 
     return render_template("product.html") 
 
 
  
主代码main.py如下:
 
 
  from flask import Flask, render_template, url_for, request, redirect, session 
 
 
  from news import news #导入news蓝图 
 
 
  from user import user #导入user蓝图 
 
 
  from product import product #导入product蓝图 
 
 
 
     
 
 
  
 
  app=Flask(__name__) 
 
 
  app.secret_key='any random string' 
 
 
  
 
  urls=[news,user,product] #将三个路由构建数组 
 
 
  for url in urls: 
 
 
     app.register_blueprint(url) #将三个路由均实现蓝图注册到主app应用上 
 
 
 
     
 
 
  
 
  @app.route('/') 
 
 
  def index(): 
 
 
     userinfo='' 
 
 
     return render_template("index.html",data=userinfo) 
 
 
 
     
 
 
  
 
  if __name__=="__main__": 
 
 
     print(app.url_map) #打印url结构图 
 
 
     app.run(port=2020,host="127.0.0.1",debug=True) 
 
 
  
保存好几个文件后,从main.py中执行启动服务,在浏览器地址栏里可以顺利浏览本案例实现的网站,这已经测试正常通过。
 
蓝图模块非常有利于网站业务逻辑的部署,大大提高维护有效性,尤其是在复杂业务处理时分而治之思想非常有效。另外在页面开发过程中,还有网页页面的一些共享需要,比如对于一个网站,页面头部和底部基本都是相同的,有时候侧边导航栏也是一样的,那在开发时就没有必要每个页面都重新写一遍相同内容的代码。我们可以将这些公用相同的内容做成模板,在需要的页面里调用即可。
 
备注:对于数据库,采用的是slite3。数据名:web,表名称:news
 
数据库的操作文件dbUtil.py源码如下:
 
 
  class DBUtils: 
 
 
  def __init__(self, dbName): # 连接数据库 
 
 
     import sqlite3 
 
 
     self.conn = sqlite3.connect(dbName) 
 
 
 
     
 
 
  
 
  def db_action(self, sql, actionType=0): # 进行相关业务操作 
 
 
     try: 
 
 
        res = self.conn.execute(sql) 
 
 
        if actionType == 1: # 当操作类型为1时代表为查询业务,返回查询列表 
 
 
          return res.fetchall() 
 
 
        else: # 当操作类型不为1时代表为新增、删除或更新业务,返回逻辑值 
 
 
          return True 
 
 
     except ValueError as e: 
 
 
        print(e) 
 
 
 
     
 
 
  
 
  def close(self): # 关闭数据库 
 
 
     self.conn.commit() 
 
 
     self.conn.close() 
 
 
 
     
 
 
  
 
  def initDB(): 
 
 
     #1.创建数据库 
 
 
     # db=DBUtils('web.db') 
 
 
     # #2.创建新闻表 
 
 
     # sql='create table news (newsid int, content text, author text)' 
 
 
     # if db.db_action(sql,0)==True: 
 
 
     # print("创建新闻表成功!") 
 
 
     # else: 
 
 
     # print("try again1") 
 
 
     # #3.新增新闻 
 
 
     # sql= "insert into news values(1,'武汉疫情非常严重,口罩等急需物品短缺','cao')," \ 
 
 
     # "(2,'全国人民都给武汉加油,疫情肯定会控制住','cao')" 
 
 
     # if db.db_action(sql,0)==True: 
 
 
     # print("新增新闻表成功!") 
 
 
     # else: 
 
 
     # print("try again1") 
 
 
  
 
     db=DBUtils('web.db') #链接web数据库 
 
 
     sql='select * from news' #组装查询sql语句 
 
 
     newslist=db.db_action(sql,1) #查询处理并返回列表 
 
 
     print('newslist:',newslist) 
 
 
  
 
 
  if __name__ == '__main__': 
 
 
     initDB() 
 
 
  
在initDB()函数中,有创建表和新增数据语句,打开后执行即可生成数据库和表。
         
    
全部评论