Flask項目示例目錄


  Flask不同於Django,Django在創建程序時自動得到必要的目錄文件,而Flask則只有一個空文件夾,所以關於Flask項目的目錄我們需要自行配置。

  首先利用pycharm創建一個項目,在根目錄下創建一個app文件夾(app文件)、一個utils文件夾(用於放數據庫連接池)、一個manage.py文件和一個settings.py文件。這里我還創建了一個auth文件夾,寫了一個驗證登錄的py文件

 

  首先,我們要在app文件夾下依次創建一下內容:

    •   static文件夾:用於放靜態文件
    •   templates文件夾:用於放置html模板文件
    •         views文件夾:用於放置視圖函數
    •         __init__.py文件:注冊app到啟動文件,一會兒我們會在這里大做文章
    •         models.py文件:用於放置創建表的類

  在__init__.py中,需要做的是引入Flask-SQLAlchemy、創建app、設置配置文件、注冊藍圖和注冊組件

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask

from auth.auth import Auth
from flask_session import Session

# 1. 引入Flask-SQLAlchemy
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()#實例化SQLAlchemy


from .views.account import account
from .views.main import main
from .views.user import user

# 3. 導入models中的表
from .models import *

#創建app
def create_app():
    app = Flask(__name__)
    app.debug = True
    app.secret_key = 'sdiusdfsdf'#自定義的session秘鑰
    # 設置配置文件
    app.config.from_object('settings.DevelopmentConfig')

    # 注冊藍圖
    app.register_blueprint(account)
    app.register_blueprint(user)
    app.register_blueprint(main)

    # 注冊組件
    # Session(app)
    Auth(app)

    # 2. 注冊 Flask-SQLAlchemy
    # 這個對象在其他地方想要使用
    # SQLAlchemy(app)
    db.init_app(app)

    return app
#得到了一個app
app文件夾下的_init__.py

 

  然后,在啟動文件manage.py中導入創建的app,創建自定義命令后寫下run

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
被斃掉了
    # 5. 創建和刪除表
    以后執行db.create_all()
    以后執行db.drop_all()
新第5步:
    安裝 pip3 install Flask-Migrate
"""


import os
from flask_script import Manager, Server
# 5.1 導入
from flask_migrate import Migrate, MigrateCommand
from app import create_app, db

app = create_app()
manager = Manager(app)
# 5.2 創建migrate示例
migrate = Migrate(app, db)


@manager.command
def custom(arg):
    """
    自定義命令
    python manage.py custom 123
    :param arg:
    :return:
    """
    print(arg)


@manager.option('-n', '--name', dest='name')
@manager.option('-u', '--url', dest='url')
def cmd(name, url):
    """
    自定義命令
    執行: python manage.py  cmd -n wupeiqi -u http://www.oldboyedu.com
    :param name:
    :param url:
    :return:
    """
    print(name, url)


@manager.command
def import_news(path):
    """
    批量導入
    :param name:
    :param url:
    :return:
    """
    import xlrd
    from xlrd.book import Book
    from xlrd.sheet import Sheet
    from xlrd.sheet import Cell
    workbook = xlrd.open_workbook(path)
    sheet_names = workbook.sheet_names()
    # sheet = workbook.sheet_by_name('工作表1')
    sheet = workbook.sheet_by_index(0)

    # 循環Excel文件的所有行
    for row in sheet.get_rows():
        # print(row)
        # 循環一行的所有列
        for col in row:
            # 獲取一個單元格中的值
            print(col.value, end=';')
        print('')



"""
# 數據庫遷移命名
    python manage.py db init
    python manage.py db migrate
    python manage.py db upgrade
"""
# 5.3 創建db命令,以后在數據庫操作的時候都可使用db
manager.add_command('db', MigrateCommand)



"""
# 自定義命令
    python manage.py runserver 
"""
manager.add_command("runserver", Server())



"""
生成當前環境的所有依賴: requirements.txt
    pip3 freeze > requirements.txt
    
生成當前程序的所有依賴: requirements.txt
    pip3 install pipreqs
    pipreqs ./
    
"""




if __name__ == "__main__":
    manager.run()
manage.py

 

  接下來在settings.py文件中配置好相應的數據庫信息,在utils文件夾下創建文件,寫入數據庫連接池的內容

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import redis


class BaseConfig(object):
    SESSION_TYPE = 'redis'  # session類型為redis
    SESSION_KEY_PREFIX = 'session:'  # 保存到session中的值的前綴
    SESSION_PERMANENT = False  # 如果設置為True,則關閉瀏覽器session就失效。
    SESSION_USE_SIGNER = False  # 是否對發送到瀏覽器上 session:cookie值進行加密

    SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:123@127.0.0.1:3306/flask_cata?charset=utf8"
                                             #數據庫用戶名:密碼@host:port/數據庫名?編碼
    SQLALCHEMY_POOL_SIZE = 2
    SQLALCHEMY_POOL_TIMEOUT = 30
    SQLALCHEMY_POOL_RECYCLE = -1

    # 追蹤對象的修改並且發送信號
    SQLALCHEMY_TRACK_MODIFICATIONS = False


class ProductionConfig(BaseConfig):
    pass


class DevelopmentConfig(BaseConfig):
    pass


class TestingConfig(BaseConfig):
    pass
settings.py
import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection
POOL = PooledDB(
    creator=pymysql,  # 使用鏈接數據庫的模塊
    maxconnections=6,  # 連接池允許的最大連接數,0和None表示不限制連接數
    mincached=2,  # 初始化時,鏈接池中至少創建的空閑的鏈接,0表示不創建
    maxcached=5,  # 鏈接池中最多閑置的鏈接,0和None不限制
    maxshared=3,  # 鏈接池中最多共享的鏈接數量,0和None表示全部共享。PS: 無用,因為pymysql和MySQLdb等模塊的 threadsafety都為1,所有值無論設置為多少,_maxcached永遠為0,所以永遠是所有鏈接都共享。
    blocking=True,  # 連接池中如果沒有可用連接后,是否阻塞等待。True,等待;False,不等待然后報錯
    maxusage=None,  # 一個鏈接最多被重復使用的次數,None表示無限制
    setsession=[],  # 開始會話前執行的命令列表。如:["set datestyle to ...", "set time zone ..."]
    ping=0,
    # ping MySQL服務端,檢查是否服務可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
    # host='47.93.4.198',
    host='127.0.0.1',#本機host
    port=3306,#數據庫默認端口即3306
    user='root',#數據庫用戶名
    password='123',#數據庫密碼
    database='flask_cata',#數據庫名
    charset='utf8'
)
utils\pool\db_pool.py
"""

# 方式一
# helper = SQLHelper()
# helper.open()
# result = helper.fetchone('select * from users where name=%s and pwd = %s',[request.form.get('user'),request.form.get('pwd'),])
# helper.close()
# 方式二:
# with SQLHelper() as helper:
#     result = helper.fetchone('select * from users where name=%s and pwd = %s',[request.form.get('user'),request.form.get('pwd'),])
# if result:
#     current_app.auth_manager.login(result['name'])
#     return redirect('/index')


"""

from utils.pool import db_pool
import pymysql


class SQLHelper(object):
    def __init__(self):
        self.conn = None
        self.cursor = None

    def open(self, cursor=pymysql.cursors.DictCursor):
        self.conn = db_pool.POOL.connection()
        self.cursor = self.conn.cursor(cursor=cursor)

    def close(self):
        self.cursor.close()
        self.conn.close()

    def fetchone(self, sql, params):
        cursor = self.cursor
        cursor.execute(sql, params)
        result = cursor.fetchone()

        return result

    def fetchall(self, sql, params):
        cursor = self.cursor
        cursor.execute(sql, params)
        result = cursor.fetchall()
        return result

    def __enter__(self):
        self.open()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

        # with SQLHelper() as obj:
        #
        #     print(obj)
        #     print('正在執行')
utils\pool\sqlhelper.py

 

到這里,程序的基本框架就設定好了。

接下來就是具體項目的內容,這里舉一個簡單的栗子

  在models.py中創建表

"""

# 方式一
# helper = SQLHelper()
# helper.open()
# result = helper.fetchone('select * from users where name=%s and pwd = %s',[request.form.get('user'),request.form.get('pwd'),])
# helper.close()
# 方式二:
# with SQLHelper() as helper:
#     result = helper.fetchone('select * from users where name=%s and pwd = %s',[request.form.get('user'),request.form.get('pwd'),])
# if result:
#     current_app.auth_manager.login(result['name'])
#     return redirect('/index')


"""

from utils.pool import db_pool
import pymysql


class SQLHelper(object):
    def __init__(self):
        self.conn = None
        self.cursor = None

    def open(self, cursor=pymysql.cursors.DictCursor):
        self.conn = db_pool.POOL.connection()
        self.cursor = self.conn.cursor(cursor=cursor)

    def close(self):
        self.cursor.close()
        self.conn.close()

    def fetchone(self, sql, params):
        cursor = self.cursor
        cursor.execute(sql, params)
        result = cursor.fetchone()

        return result

    def fetchall(self, sql, params):
        cursor = self.cursor
        cursor.execute(sql, params)
        result = cursor.fetchall()
        return result

    def __enter__(self):
        self.open()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

        # with SQLHelper() as obj:
        #
        #     print(obj)
        #     print('正在執行')
models.py

 

  通過python manage.py db init      python manage.py db migrate      python manage.py db upgrade三條命令進行數據庫遷移創建表,得到migrations文件夾

  在views文件夾下創建視圖函數,並配置路由。在templates文件夾下創建模板html,在static下創建靜態文件,基本項目就成型了

views:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Blueprint, request, render_template, redirect, session, current_app
from app import models
from app import db
from sqlalchemy import orm

account = Blueprint('account', __name__)


@account.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':

        """
        執行SQL
        方式一:
            result = db.session.query(models.User.id,models.User.name).all()
            db.session.remove()
        方式二:
            result = models.Users.query.all()
        """
        """
        示例:
            # 通配符
            ret = db.session.query(Users).filter(Users.name.like('e%')).all()
            ret = db.session.query(Users).filter(~Users.name.like('e%')).all()
            
            # 限制
            ret = db.session.query(Users)[1:2]
            
            # 排序
            ret = db.session.query(Users).order_by(Users.name.desc()).all()
            ret = db.session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()
            
            db.session.remove()
            

        """
        return render_template('login.html')
    else:
        return render_template('login.html')
account.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Blueprint, request, render_template, redirect

main = Blueprint('main', __name__)


@main.route('/index')
def index():
    # with SQLHelper() as helper:
    #     user_list = helper.fetchall('select * from users',[])

    return render_template('index.html')
main.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Blueprint

user = Blueprint('user', __name__)


@user.route('/users')
def users():
    return 'users'
user.py

templates:

{% extends 'layout.html' %}

{% block title %}首頁{% endblock %}

{% block body %}
<table>
    <h1>歡迎登錄:{{ session.get('user') }}</h1>
    <ul>
        {% for row in user_list %}
        <li>{{ row }}</li>
        {% endfor %}
    </ul>
</table>
{% endblock %}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <!-- <link rel="stylesheet" href="/static/css/commons.css" /> -->
    <link rel="stylesheet" href="{{ url_for('static',filename='css/commons.css') }}" />

    {% block css %}{% endblock %}
</head>
<body>
    <div class="pg-header"></div>
    <div class="pg-body">
        {% block body %}{% endblock %}
    </div>

    {% block js %}{% endblock %}
</body>
</html>
layout.html(基板)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="post">
    <input type="text" name="user">
    <input type="text" name="pwd">
    <input type="submit" value="提交">
</form>
</body>
</html>
login.html

 

 

附:

alembic==0.9.6
blinker==1.4
certifi==2017.11.5
chardet==3.0.4
click==6.7
DBUtils==1.2
docopt==0.6.2
Flask==0.12.2
Flask-Migrate==2.1.1
Flask-Script==2.0.6
Flask-Session==0.3.1
Flask-SQLAlchemy==2.3.2
idna==2.6
itsdangerous==0.24
Jinja2==2.10
Mako==1.0.7
MarkupSafe==1.0
pipreqs==0.4.9
PyMySQL==0.8.0
python-dateutil==2.6.1
python-editor==1.0.3
PyTyrion==1.0.1
requests==2.18.4
six==1.11.0
SQLAlchemy==1.2.0
urllib3==1.22
Werkzeug==0.14.1
WTForms==2.1
xlrd==1.1.0
yarg==0.1.9
requirement.txt
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import request, session,redirect


# 登錄成功時 _request_ctx_stack.top.user = user


class Auth(object):
    def __init__(self, app=None):
        self.app = app
        if app:
            self.init_app(app)

    def init_app(self, app):
        app.auth_manager = self

        app.before_request(self.check_login)
        app.context_processor(self.auth_context_processor)

    def auth_context_processor(self):
        name = session.get('user')
        return dict(current_user=name)

    def check_login(self):
        # print(request.url)
        # print(request.path)
        if request.path == '/login':
            return None

        if session.get('user'):
            return None
        return redirect('/login')

    def permission(self):
        pass

    def login(self,data):
        session['user'] = data
auth.py

 

 

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM