测开之路一百四十一:蓝图实现程序模块化

把每一个模块独立出来,然后在主app里面注册,这样就实现了模块之间互不干扰

新建蓝图

artcle.views.py

"""article蓝图"""from flask import request, render_template, redirect, url_forfrom flask import Blueprint

article = Blueprint(‘article‘, __name__)

@article.route(‘/articles/‘)def article_list():    return render_template(‘article-list.html‘)

@article.route(‘/articles/<id>/‘)def articles_id(id=None):    item = {‘id‘: id}    return render_template(‘artocle-detail.html‘, item=item)

artcle-list.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>文章列表</title></head><body><h1>文章列表</h1>

</body></html>

artcle-detail.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>文章信息</title></head><body><h1>文章标题{{ item.id }}</h1></body></html>

注册蓝图:app.register_blueprint(蓝图名)

main.py

请求

蓝图下基于类和方法的视图

"""article蓝图"""from flask import request, render_template, redirect, url_forfrom flask import Blueprintfrom flask.views import MethodView

article = Blueprint(‘article‘, __name__)

class ArticleList(MethodView):    def get(self):        return render_template(‘article-list.html‘)

    def post(self):        pass

class ArticlesId(MethodView):    def get(self, id=None):        item = {‘id‘: id}        return render_template(‘artocle-detail.html‘, item=item)

article.add_url_rule(‘/articles/‘, view_func=ArticleList.as_view(‘article_list‘))article.add_url_rule(‘/articles/<int:id>/‘, view_func=ArticlesId.as_view(‘articles_id‘))

# @article.route(‘/articles/‘)# def article_list():#     return render_template(‘article-list.html‘)

# @article.route(‘/articles/<id>/‘)# def articles_id(id=None):#     item = {‘id‘: id}#     return render_template(‘artocle-detail.html‘, item=item)

前面已经注册artcle,所以不用管,直接访问

注册蓝图时加默认前缀,实现模块分类

新建一个product蓝图

"""product蓝图"""

from flask import Blueprint

product = Blueprint(‘product‘, __name__)

@product.route(‘/‘)  # 由于注册蓝图时已添加前缀products, 所以访问时真实路径为/products/def product_list():    return ‘产品列表页‘

@product.route(‘/id/‘)  # 由于注册蓝图时已添加前缀products, 所以访问时真实路径为/products/id/def product_id(id=None):    return ‘产品详情‘ + str(id)

主入口里面注册

访问

蓝图生成链接重定向

找到蓝图注册名和要重定向的终结点

在base.html里面添加中定向:蓝图名.终结点名

article蓝图

"""article蓝图"""from flask import request, render_template, redirect, url_forfrom flask import Blueprintfrom flask.views import MethodView

article = Blueprint(‘article‘, __name__)

class ArticleList(MethodView):    def get(self):        return render_template(‘article-list.html‘)

    def post(self):        pass

class ArticlesId(MethodView):    def get(self, id=None):        item = {‘id‘: id}        return render_template(‘artocle-detail.html‘, item=item)

article.add_url_rule(‘/‘, view_func=ArticleList.as_view(‘article_list‘))article.add_url_rule(‘/<int:id>/‘, view_func=ArticlesId.as_view(‘articles_id‘))

# @article.route(‘/articles/‘)# def article_list():#     return render_template(‘article-list.html‘)

# @article.route(‘/articles/<id>/‘)# def articles_id(id=None):#     item = {‘id‘: id}#     return render_template(‘artocle-detail.html‘, item=item)

product蓝图

"""product蓝图"""

from flask import Blueprint

product = Blueprint(‘product‘, __name__)

@product.route(‘/‘)  # 由于注册蓝图时已添加前缀products, 所以访问时真实路径为/products/def product_list():    return ‘产品列表页‘

@product.route(‘/id/‘)  # 由于注册蓝图时已添加前缀products, 所以访问时真实路径为/products/id/def product_id(id=None):    return ‘产品详情‘ + str(id)

main.py

# coding:utf-8import sqlite3from datetime import datetime, timedeltafrom flask import Flask, request, render_template, redirect, url_for, g, send_from_directory, session, make_response

app = Flask(__name__)

DATABASE = r‘.\db\feedbach.db‘

‘=======================封装sql助手函数=============================‘

def make_dicts(cursor, row):    """ 将游标获取的Tuple根据数据库列表转换为dict """    return dict((cursor.description[idx][0], value) for idx, value in enumerate(row))

def get_db():    """ 获取(简历数据库链接)    g: flask内置的变量:g = LocalProxy(partial(_lookup_app_object, "g"))    """    db = getattr(g, ‘_database‘, None)    if not db:        db = g._database = sqlite3.connect(DATABASE)        db.row_factory = make_dicts    return db

def execute_sql(sql, params=()):    """ 执行sql语句不返回数据结果 insert、update、delete """    c = get_db().cursor()    c.execute(sql, params)    c.connection.commit()

def query_sql(sql, params=(), one=False):    """ 查询数据 one=False的时候返回多条"""    c = get_db().cursor()    result = c.execute(sql, params).fetchall()    c.close()    return (result[0] if result else None) if one else result

@app.teardown_appcontext  # 在当前app上下文销毁时执行def close_connection(exeption):    """ 关闭数据库 """    db = getattr(g, ‘_database‘, None)    if db is not None:        db.close()

‘========================================================================‘

@app.route("/")def index():    return render_template(‘base.html‘)

app.secret_key = ‘qoihf2397r21380r2/./ad‘  # 加密的安全码,越复杂越好,flask后台自动进行加密

# @app.route(‘/login/‘, methods=[‘GET‘, ‘POST‘])# def login():#     """ 登录 """#     if request.method == ‘POST‘:#         username = request.form.get(‘username‘)#         password = request.form.get(‘password‘)#         sql = ‘select count(*) as [Count] from UserInfo where username = ? and password = ?‘#         result = query_sql(sql, (username, password), True)#         if int(result.get(‘Count‘)) > 0:#             print(username)#             session[‘admin‘] = username  # 已登录的用户保存到session#             return redirect(url_for(‘list‘))#         return ‘用户名或密码错误‘#     return render_template(‘login.html‘)

# 模板继承@app.route("/feedback/")def feedback():    return render_template(‘post.html‘)

UPLOAD_FOLDER = r‘.\uploads‘  # 声明存文件的目录ALLOWED_EXTENSIONS = [‘.jpg‘, ‘.png‘, ‘.gif‘]  # 允许上传的后缀,限制上传格式

import os

def allowed_file(filename):    """ 判断文件是否允许上传 """    # filename = ‘asdasdasd.jpg‘    _, ext = os.path.splitext(filename)    return ext.lower() in ALLOWED_EXTENSIONS  # 把后缀转为小写

@app.route("/post_feedback/", methods=["POST"])def post_feedback():    """ 提交视图 """    if request.method == ‘POST‘:  # 如果是post请求就获取表单值        subject = request.form.get(‘subject‘, None)        categoryid = request.form.get(‘category‘, 1)        username = request.form.get(‘username‘)        email = request.form.get(‘email‘)        body = request.form.get(‘body‘)        release_time = str(datetime.now())        state = 0        img_path = None        # 提交的内容包含图片,就获取图片名字用于插入数据库,并保存图片        if request.files.get(‘file_s‘, None):            img = request.files[‘file_s‘]            if allowed_file(img.filename):                # 为防止文件名重复,重命名文件                img_path = datetime.now().strftime(‘%Y%m%d%H%M%f‘) + os.path.splitext(img.filename)[1]                img.save(os.path.join(UPLOAD_FOLDER, img_path))        print(subject, categoryid, username, email, body, state, release_time, img_path)        conn = sqlite3.connect(DATABASE)        c = conn.cursor()        # 防止sql注入,用?代替值        sql = "insert into feedback (Subjeck, CategoryID, UserName, Email, Body, State, ReleaseTime, Image) values (?,?,?,?,?,?,?,?)"        c.execute(sql, (subject, categoryid, username, email, body, state, release_time, img_path))        conn.commit()        conn.close()        # 为防止因卡顿引起重复提交,提交过后跳转到填写页面        return redirect(url_for(‘feedback‘))

@app.route("/list/")def list():    """ 展示所有问题 """    # 访问/list/的时候,如果session里面没有admin,就返回登录页    if session.get(‘admin‘, None) is None:        return redirect(url_for(‘login‘))    key = request.args.get(‘key‘, ‘‘)    sql = ‘select f.ROWID,f.*,c.CategoryName from feedback f INNER JOIN category c on c.ROWID = f.CategoryID where f.Subjeck like ? order by f.ROWID‘    feedbacks = query_sql(sql, (f‘%{key}%‘,))    return render_template(‘feedback-list.html‘, items=feedbacks)

@app.route(‘/del/<id>/‘)def delete_feedback(id=0):    """ 删除问题 ,前端传id"""    conn = sqlite3.connect(DATABASE)    c = conn.cursor()    sql = "delete from feedback where ROWID = ?"    c.execute(sql, (id,))    conn.commit()    conn.close()    return redirect(url_for(‘list‘))

@app.route(‘/profile/<filename>‘)def render_file(filename):    """ 呈现特定目录下的资源,用于jinja2模板调用渲染服务器的图片"""    return send_from_directory(UPLOAD_FOLDER, filename)  # uploads + feilename

@app.route("/edit/<id>/")def edit(id=None):    """ 根据前端传过来的id返回编辑的html """    # 访问/edit/<id>/的时候,如果session里面没有admin,就返回登录页    if session.get(‘admin‘, None) is None:        return redirect(url_for(‘login‘))    # 获取绑定的下拉列表    sql = "select ROWID,CategoryName from category"    categories = query_sql(sql)    # 获取当前id的信息,并绑定至form表单,以备修改    sql = "select rowid,* from feedback where rowid = ?"    curren_feedback = query_sql(sql, (id,), True)    # return str(curren_feedback)  # 查看查出来的数据顺序,方便html渲染排序    return render_template(‘edit.html‘, categories=categories, item=curren_feedback)

@app.route("/save_edit/", methods=[‘POST‘])def save_edit():    """ 保存编辑 """    if request.method == ‘POST‘:        id = request.form.get(‘rowid‘, None)        reply = request.form.get(‘reply‘)        state = 1 if request.form.get(‘state‘, 0) == ‘on‘ else 0        sql = ‘update feedback set Reply=?, State=? where rowid=?‘        conn = sqlite3.connect(DATABASE)        c = conn.cursor()        c.execute(sql, (reply, state, id))        conn.commit()        conn.close()    return redirect(url_for(‘list‘))

@app.route(‘/logout/‘)def logout():    """ 退出登录,删除session跳转到登录页 """    session.pop(‘admin‘)    return redirect(url_for(‘list‘))  # 为了防止在页面上点后退的情况,让list视图来执行让页面跳转到登录页

@app.route(‘/setck/‘)def setck():    """ 添加cookie,timedelta由datatime导入 """    response = make_response(‘ok‘)    response.set_cookie(‘username‘, ‘aaa‘, path=‘/‘, expires=datetime.now() + timedelta(days=7))    # set_cookie 参数    # dmain=‘baidu.com‘  指定cookie只对baidu.com起作用    # path=‘/‘  此cookie能访问的路径    # httponly=True  只能http访问,默认关闭    # max_age=60  cookie生命周期,默认为None,浏览器关闭时销毁,单位为秒    # expires=datetime.now() + timedelta(days=7)  # 指定过期时间为7天    return response

@app.route(‘/getck/‘)def getck():    """ 获取cookie  request.cookies.get(‘xxx‘) """    ck = request.cookies.get(‘username‘)    if ck:        return ck    return ‘未获取到cookie‘

@app.route(‘/rmck/‘)def remove_cookie():    """ 删除cookie,    由于不允许直接操作硬盘,所以采用更新cookie生效时间的方法    找到cookie,把生效时间设为当前时间之前    """    resp = make_response(‘删除cookie‘)    # 把生效时间设为上一秒    resp.set_cookie(‘username‘, ‘‘, expires=datetime.now() + timedelta(minutes=-1))    return resp

# 调用基于类的视图from account.views import RegUser, UserLogin

# 为导入的基于类的视图添加分配url规则# 第一个参数:地址,第二个login为终结点,即视图函数名,可用于重定向# app.add_url_rule(‘/login/‘, view_func=UserLogin.as_view(‘login‘))# app.add_url_rule(‘/reg/‘, view_func=RegUser.as_view(‘reg‘))

# 调用基于方法的视图from account.views import ARegUser

app.add_url_rule(‘/login/‘, view_func=UserLogin.as_view(‘login‘))app.add_url_rule(‘/reg/‘, view_func=ARegUser.as_view(‘reg‘))

# 注册蓝图from article.views import articlefrom product.views import product

app.register_blueprint(article, url_prefix=‘/articles/‘)  # 注册时添加地址栏前缀app.register_blueprint(product, url_prefix=‘/products/‘)  # 注册时添加地址栏前缀

if __name__ == ‘__main__‘:    app.run(        debug=True    )

原文地址:https://www.cnblogs.com/zhongyehai/p/11483933.html

时间: 2024-10-21 10:49:01

测开之路一百四十一:蓝图实现程序模块化的相关文章

测开之路一百四十七:用WTForms实现编辑功能

接上一篇的内容 把原先的数据库模型全部给默认值,后面form赋值的时候就不用传位置参数了 把视图逻辑修改一下 # 视图层from datetime import datetimefrom flask.views import MethodViewfrom flask import render_template, redirect, url_for, request from personal.models import db, Employee, Departmentfrom personal

测开之路一百四十四:ORM之SQLAlchemy查询

在上一篇的基础上,插入数据 查询 Department.query.all() # 用表对象查db.session.query(Department).all() # 用db对象查 查询前两条,直接python截取前两条数据 排序 默认升序:order_by(排序的字段名) 倒序:从sqlalchemy导入desc 查询单个指定字段 查询多个指定字段 只用一个变量接收多个查询结果的时候,SQLAlchemy默认用namedtuple进行命名处理 namedtuple结构: 别名:label(别名

测开之路一百四十八:WTForms表单验证

使用WTForms表单验证,可以在数据建模时就设置验证信息和错误提示 创建模型时,设置验证内容,如必填.格式.长度 from flask_wtf import Formfrom wtforms import StringField, PasswordField, BooleanFieldfrom wtforms import validators class UserRegForm(Form): username = StringField('用户名', [validators.DataRequ

测开之路五十二:蓝图的用法

目录结构 html <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>蓝图渲染</title></head><body><h1>这里是蓝图渲染</h1></body></html> 子app(创建不同的蓝图,如接口测试.ui测试.性能测试)

测开之路七十七:性能测试蓝图之js

//定义全局的editor = nullvar editor = null; //ace_editor的初始化函数function ace_editor() { var editor = ace.edit("editor"); //初始化对象,"editor"为前端页面的id //设置风格和语言(更多风格和语言,请到github上相应目录查看) //editor.setTheme("ace/theme/clouds"); //编辑界面的主题--云

测开之路七十六:性能测试蓝图之html

<!-- 继承base模板 -->{% extends 'base.html' %} {% block script %} <!-- 从cdn引入ace edter的js --> <script src="https://cdn.bootcss.com/ace/1.4.5/ace.js"></script> <script src="https://cdn.bootcss.com/ace/1.4.5/mode-python

测开之路七十八:性能测试蓝图之视图层

from flask import requestfrom flask import jsonifyfrom flask import Blueprintfrom flask import render_templatefrom performance.logic import Logic performance = Blueprint('performance', __name__, static_folder='static', template_folder='templates', ur

测开之路十一:作用域、闭包和修饰器

作用域 L (Local) 局部作用域E (Enclosing) 闭包函数外的函数中G(Global) 全局作用域B (Built-in) 内建作用域locals()和globals()local -> enclosing-> global -> build-in 闭包 1.闭包函数必须有内嵌函数2.内嵌函数需要引用嵌套函数的变量3.闭包函数必须返回内嵌函数 第一层def的参数为函数名,第二层def的参数为第一层传的函数需要的参数 闭包用法: 1.直接调用 2.修饰器调用, 修饰器的本质

测开之路五十一:代码实现MongoDB增删改查

初始化时连接.析构时断开连接 from pymongo import MongoClient class Mogo(object): def __init__(self, host='127.0.0.1', port=27017): """ 初始化时连接 """ self.connect = MongoClient(host, port) def __del__(self): """ 析构时断开连接 "&q