android开发小项目实例_项目实战:使用Python的Flask模块快速开发一个web入门小项目...

71dc1172798a2279de26b933ee85e0ad.png

平时做数据分析挖掘的结果,难免会需要在Web上展示出来,这样更有逼格。那么,开发web页面难吗?使用Java开发门槛太高,一堆注解绝对让你投降;使用PHP开发,好像太骚了。其实,我们需要有这么一个工具,既能做数据分析挖掘,又能做web展示,非你莫属了——Python。

这里,选择Python的轻量级框架Flask,开发速度更快,开发一个简单的话题发布,支持基本的登陆、注销功能。

项目截图

未登陆前

位登陆前,支持浏览,只读权限,右上角有登陆按钮。

3dcf01eca8f81654bd77cda429162304.png

登陆后

登陆后,可以发布主题,可以注销。

875dbe7054797d801e77c0ef112dd040.png

可以看到,功能非常简单,这是第一步,有了基础才能自己学习,做出炫酷的分析结果。

项目过程

项目过程,分为以下几步:

  • web服务的第一个请求之前,需要初始化数据库连接;

  • 游客(未登陆状态),可以看到所有话题;

  • 为了简化,只有一个用户硬编码,没有用户表;

  • 登陆之后,可以发布主题,数据保存到数据库;

  • 注销后,回到游客状态;

项目代码结构

这个项目是flask官方入门项目,取名flaskr,工程目录结构如下:

d2cd6348f82c80706c83977350e934bf.png

  • flask目录:这里暂且记为项目根目录;

  • static:存放网站静态文件,包括css样式,图片文件等;

  • templates:前端jinja2 html模板文件;

  • entries.db:SQLite3数据文件;

  • flaskr.py:Python项目主要代码文件;

  • schema.sql:建表文件,这里需要一张表,保存用户发布的话题;

最后,会上完整代码,复制过去可以直接运行的。

初始化上下文环境

首先初始化应用和一些变量,包括Flask实例,g对象,如果使用session,需要初始化一个app.secret_key

import os
import sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \
     render_template, flash

app = Flask(__name__, instance_path='D:/我的文件/Codes/PyCode/web/flask/flaskr')
app.config['USERNAME'] = 'name'
app.config['PASSWORD'] = 'password'
app.secret_key = 'ajflafoo8qm.mgaj'

# DATABASE = 'D:/我的文件/Codes/PyCode/web/flask/flaskr/entries.db'
DATABASE = os.path.join(os.getcwd(), 'entries.db')

注意:自己电脑上面执行的时候,D:/我的文件/Codes/PyCode/web/flask/flaskr,这个是我的SQLite3地址,需要换成自己的,对应地址。

初始化数据库

由于是"Hello world"入门项目,这里使用的数据库是小型的磁盘型数据库SQLite3,没必要连接大型数据库。

SQLite3何许人也?

SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。

连接数据库,需要获取数据库连接,SQLite3数据库不错在,则会新建一个文件夹,名字为数据库名:

def get_db():
    """connect to special database"""
    return sqlite3.connect(DATABASE)

第一次运行需要初始化数据库和表,调用init_table方法即可。

def init_table():
    """first run create table"""
    db = get_db()
    result = db.cursor().execute(
        "SELECT count(*) FROM sqlite_master WHERE type = 'table' AND name = 'entries'").fetchall()
    table_exists = result[0][0] == 1

    # 不存在,则创建表
    if not table_exists:
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
        db.commit()
    else:
        print('entries already exists .')

    db.close()

每一个请求之前@app.before_request需要连接数据库,request请求之后@app.teardown_request关闭数据库:

@app.before_request
def before_request():
    g.db = get_db()


@app.teardown_request
def teardown_request(exception):
    if hasattr(g, 'db'):
        g.db.close()

用户登陆、注销

通常,用户登陆后,才有权限发表话题,注销后就是游客身份,只能看,不能发布话题。

显示所有发布的话题

@app.route('/')
def show_entries():
    """显示条目"""
    sql = 'select title, text from entries order by id desc'
    cursor = g.db.cursor()
    entries = [dict(title = row[0], text = row[1]) for row in cursor.execute(sql).fetchall()]
    cursor.close()
    return render_template('show_entries.html', entries = entries)

用户登陆

为了简单起见,没有建用户表,只是在内存中定义了一个用户,用户名:name,密码:password。

@app.route('/login', methods=['GET', 'POST'])
def login():
    """登陆函数"""
    error = None
    if request.method == 'POST':
        if request.form['username'] != app.config['USERNAME']:
            error = 'Invalid username'
        elif request.form['password'] != app.config['PASSWORD']:
            error = 'Invalid password'
        else:
            session['logged_in'] = True
            flash('You were logged in')
            return redirect(url_for('show_entries'))
    return render_template('login.html', error = error)

用户注销

注销后,直接重定向到主页。

@app.route('/logout')
def logout():
    """注销函数"""
    session.pop('logged_in', None)
    flash('You were logged out')
    return redirect(url_for('show_entries'))

登陆用户发布话题

用户登陆后,可以发布话题,内容存在SQLite3数据库里面,用户每次刷新或者跳转到主页需要读取数据库,显示。通过表单发送数据,methods是POST。

@app.route('/add', methods=['POST'])
def add_entry():
    if not session.get('logged_in'):
        abort(401)
    sql = 'insert into entries(title, text) values(?, ?)'
    g.db.execute(sql, [request.form['title'], request.form['text']])
    g.db.commit()
    flash('New entry was successfully posted')
    return redirect(url_for('show_entries'))

项目完整代码

完整代码,这里还是贴出来吧,虽然不太美观,确保Python3已经安装了flask模块,否则通过pip3 install flask命令即可安装 ,代码可以直接执行

flaskr.py

这里是主要逻辑代码。

import os
import sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \
     render_template, flash

app = Flask(__name__, instance_path='D:/我的文件/Codes/PyCode/web/flask/flaskr')
app.config['USERNAME'] = 'name'
app.config['PASSWORD'] = 'password'
app.secret_key = 'ajflafoo8qm.mgaj'

# DATABASE = 'D:/我的文件/Codes/PyCode/web/flask/flaskr/entries.db'
DATABASE = os.path.join(os.getcwd(), 'entries.db')


def init_table():
    """first run create table"""
    db = get_db()
    result = db.cursor().execute(
        "SELECT count(*) FROM sqlite_master WHERE type = 'table' AND name = 'entries'").fetchall()
    table_exists = result[0][0] == 1

    # 不存在,则创建表
    if not table_exists:
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
        db.commit()
    else:
        print('entries already exists .')

    db.close()


def get_db():
    """connect to special database"""
    return sqlite3.connect(DATABASE)


"""
@app.before_request
def get_connection():
    db = getattr(g, 'db', None)
    if db is None:
        db = g.db = get_db()
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
        db.commit()
"""


@app.before_request
def before_request():
    g.db = get_db()


@app.teardown_request
def teardown_request(exception):
    if hasattr(g, 'db'):
        g.db.close()


@app.route('/')
def show_entries():
    """显示条目"""
    sql = 'select title, text from entries order by id desc'
    cursor = g.db.cursor()
    entries = [dict(title = row[0], text = row[1]) for row in cursor.execute(sql).fetchall()]
    cursor.close()
    return render_template('show_entries.html', entries = entries)


@app.route('/add', methods=['POST'])
def add_entry():
    if not session.get('logged_in'):
        abort(401)
    sql = 'insert into entries(title, text) values(?, ?)'
    g.db.execute(sql, [request.form['title'], request.form['text']])
    g.db.commit()
    flash('New entry was successfully posted')
    return redirect(url_for('show_entries'))


@app.route('/login', methods=['GET', 'POST'])
def login():
    """登陆函数"""
    error = None
    if request.method == 'POST':
        if request.form['username'] != app.config['USERNAME']:
            error = 'Invalid username'
        elif request.form['password'] != app.config['PASSWORD']:
            error = 'Invalid password'
        else:
            session['logged_in'] = True
            flash('You were logged in')
            return redirect(url_for('show_entries'))
    return render_template('login.html', error = error)


@app.route('/logout')
def logout():
    """注销函数"""
    session.pop('logged_in', None)
    flash('You were logged out')
    return redirect(url_for('show_entries'))


if __name__ == '__main__':
    # 第一次执行,需要初始化数据库,和表
    init_table()

    app.run(debug=True)

还有前端代码,就不贴出来了,完整项目已经上传到Github,点击阅读原文也可以,地址:

https://github.com/ddxygq/PyCode/tree/master/web/flask/flaskr

Github代码下载下来,可以直接执行的。

猜你可能喜欢

堆排序算法

markdown纯手撸复杂数学公式

Python爬虫解析库——BeautifulSoup4(美丽的汤)

程序员必备的一些数学基础知识

18d472c896c3c4190a1d90a2ee8f4606.png


http://www.niftyadmin.cn/n/504553.html

相关文章

socket | 基于C语言的天气客户端的实现

1024G 嵌入式资源大放送!包括但不限于C/C、单片机、Linux等。关注微信公众号【嵌入式大杂烩】,回复1024,即可免费获取! 一、前言 上一篇笔记分享了【socket笔记】TCP、UDP通信总结,这一篇分享一个用C语言写的、基于TC…

记本最新22款验机工具大全(适用于XP和vista)

记本最新22款验机工具大全(适用于XP和vista) 笔记本22款验机工具大全(适用于XP和vista)弄这个帖子的目的也就是为了广大想要买本未曾买本的朋友在购买的时候不会轻易的上当,而对于那些已经买了本本的朋友来说也是个好的…

b样条曲面绘制 opengl_UG复杂曲面叶轮的三维造型及五轴加工技术

摘要:以典型的深窄槽、大扭角、变根圆角的微型叶轮空压机转子应用为实例,基于UG建模、整体叶轮数控加工方案,包括整体叶轮的三维建模、数控加工工艺流程规划、数控加工编程等。并在五轴连动数控机床上进行实验验证,验证该整体叶轮…

程序人生 | 记一次裸辞,裸辞需三思而后行!

1024G 嵌入式资源大放送!包括但不限于C/C、单片机、Linux等。关注微信公众号【嵌入式大杂烩】,回复1024,即可免费获取! 前阵子在准备着找工作的事情,因此很少做分享。一是还没找着工作没心思做其他的事情,二…

IPsec和动态虚拟专用网(DM×××)

IPsec和动态虚拟专用网DM(动态多点) 允许管理员通过结合GRE隧道,IPsec加密和下一跳解析协议(NHRP)更好地扩展大型的和小型的IPSEC .(的星型模式hub-spoke配置会变的很复杂,尤其是spoke对spoke之间,而DM使其…

qq邮箱上传控件_“极简”的邮箱长什么样?

前言:邮箱是如今每个人必备的一个工具,工作、生活、消费、社交都离不开它,可以说非常重要,而且使用场景多,使用频率高,可以说每天都会用到。目前国内主流使用的邮箱有:国外品牌:Gmai…

图解冲突域、广播域

网络互连设备可以将网络划分为不同的冲突域、广播域。但是,由于不同的网络互连设备可能工作在OSI模型的不同层次上。因此,它们划分冲突域、广播域的效果也就各不相同。如中继器工作在物理层,网桥和交换机工作在数据链路层,路由器工…

Linux | Windows与Linux文件互享

1024G 嵌入式资源大放送!包括但不限于C/C、单片机、Linux等。关注微信公众号【嵌入式大杂烩】,回复1024,即可免费获取! 1、前言 之前分享了Linux下vim编译器简单的使用方法:【Linux笔记】Vi/Vim编辑器。如果觉得不习惯…