Python 《flask web 开发——基于python的web应用开发实战》第七章代码

##最近在自学狗书,遇到了很多问题,但最终还是坚持下来了,百度真的是个好东西,多查查百度就能解决很多问题,现在我把截至狗书第七章所有的代码都放在了这篇文章,需要的人可以借鉴一下看看自己错在哪里(已运行成功了),我顺便也把这代码就以这种方式保存了。共勉!

#config.py
import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Config:   # 所有配置类的父类,通用的配置写在这里
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
    MAIL_SERVER = os.environ.get('MAIL_SERVER', 'smtp.qq.com')
    MAIL_PORT = int(os.environ.get('MAIL_POST', '587'))
    MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS', 'true').lower() in ['true', 'on', '1']
    MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
    MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
    FLASKY_MAIL_SUBJECT_PREFIX = '[Flasky]'
    FLASKY_MAIL_SENDER = 'Flasky Admin <flasky@example.com>'
    FLASKY_ADMIN = os.environ.get('FLASKY_ADMIN')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

    @staticmethod
    def init_app(app):  # 静态方法作为配置的统一接口,暂时为空
        pass

class DevelopmentConfig(Config):    # 开发环境配置类
    DEBUG = True
    SQLALCHEMY_DATABASE_URI =os.environ.get('DEV_DATABASE') or \
                             'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')

class TestingConfig(Config):    # 测试环境配置类
    TESTING = True
    SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
                              'sqlite://'

class ProductionConfig(Config):     # 生产环境配置类
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
                              'sqlite:///' + os.path.join(basedir, 'data.sqlite')

config = {  # config字典注册了不同的配置,默认配置为开发环境,本例使用开发环境
    'development': DevelopmentConfig,
    'testing': TestingConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig
}
#app\__init__.py
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
from flask_mail import Mail
from config import config

# 由于尚未初始化所需的程序实例,所以没有初始化扩展,创建扩展类时没有向构造函数传入参数。
bootstrap = Bootstrap()
mail = Mail()
db = SQLAlchemy()

def create_app(config_name):
    '''工厂函数'''
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)# 通过config.py统一接口

    bootstrap.init_app(app)
    mail.init_app(app)
    db.init_app(app)
                # 同上

    # 附加路由和自定义错误页面,将蓝本注册到工厂函数
    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    return app
#app\main\views.py
from flask import render_template, session, redirect, url_for
from . import main
from .forms import NameForm
from .. import db
from ..models import User

@main.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.name.data).first()    # 查询数据库是否有该用户
        if user is None:    # 如果没有该用户,就保存到数据库中
            user = User(username=form.name.data)
            db.session.add(user)
            db.session.commit()
            session['known'] = False    # 通过session保存 known为False,通过web渲染需要
        else:
            session['known'] = True
        session['name'] = form.name.data
        form.name.data = ''
        return redirect(url_for('.index'))  # 通过redirect避免用户刷新重复提交
    return render_template('index.html', form=form, name=session.get('name'),
                           known=session.get('known', False))
#app\main\forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

class NameForm(FlaskForm):
    '''通过 flask-wtf 定义表单类'''
    name = StringField('What is your name ?', validators=[DataRequired()])  # 文本框
    submit = SubmitField('Submit')  # 按钮
#app\main\errors.py
from flask import render_template
from . import main

@main.app_errorhandler(404)     # 路由装饰器由蓝本提供,这里要调用 app_errorhandler 而不是 errorhandler
def page_not_found(e):
    return render_template('404.html'), 404

#app\main\__init__.py
from flask import Blueprint
# 定义蓝本
main = Blueprint('main', __name__)

from . import views, errors
#app\email.py
from threading import Thread
from flask import render_template, current_app
from flask_mail import Message
from . import mail

def send_async_mail(app, msg):
    '''创建邮件发送函数'''
    with app.app_context():
        mail.send(msg)

def send_mail(to, subject, template, **kwargs):
    app = current_app._get_current_object()
    if app.config['FLASKY_ADMIN']:
        msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,
                      sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
        msg.body = render_template(template + '.txt', **kwargs)
        msg.html = render_template(template + '.html', **kwargs)
        thr = Thread(target=send_async_mail, args=(app, msg))
        thr.start()  # 通过创建子线程实现异步发送邮件
        return thr
#app\models.py
from . import db

class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True, index=True)
    users = db.relationship('User', backref='role', lazy='dynamic')
    def __repr__(self):
        return '<Role %r>' % self.name


class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

    def __repr__(self):
        return '<User %r>' % self.username

#tests\test_basics.py
from app import create_app, db

class BasicsTestCase(unittest.TestCase):
    def setUp(self):
        self.app = create_app('testing')
        self.app_context = self.app.app_context()
        self.app_context.push()
        db.create_all()

    def tearDown(self):
        db.session.remove()
        db.drop_all()
        self.app_context.pop()

    def test_app_exists(self):
        self.assertFalse(current_app is None)

    def test_app_is_testing(self):
        self.assertTrue(current_app.config['TESTING'])
#flasky.py
import os
from app import create_app, db
from app.models import User, Role
from flask_migrate import Migrate

app = create_app(os.getenv('FLASK_CONFIG') or 'default')
migrate = Migrate(app, db)

@app.shell_context_processor
def make_shell_context():
    return dict(db=db, User=User, Role=Role)

@app.cli.command()
def test():
    import unittest
    tests = unittest.TestLoader().discover('tests')
    unittest.TextTestRunner(verbosity=2).run(tests)

if __name__ == '__main__':
    app.run()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值