Flask博客实战 - 目录结构

Flask博客实战 - 目录结构,第1张

为保证祥衫项目可持续发展,利于后期扩展,我们从开始创建项目就应该先规划好目录结构,一个好的目录结构可以让我们的项目整洁有序,并利于维护和后期进一步扩展!

之前快速上手中创建的app.py的文件便可以删除,亦或者你重新创建一个项目开始以下的内容,建议是新建一个目弯宴孙录来开始我们以下的内容!

在实际开发过程中,一个完整的项目一定是由多个不同的功能模块构成,以我们的埋链博客系统为例,主要由两个大的功能模块构成,一个是负责用户认证以及用户权限 *** 作的模块auth, 一个则是我们博客的主应用模块blog,他主要负责博客的内容/分类等一些与博客相关的功能!

为了实现以上需求,我们就需要现在虚拟环境venv的同级目录新建一个app的目录,用这个目录来统一管理各功能模块,并在其内部分别新建auth和blog目录,结构如下所示!

从以上目录可以看出,我们在每一个文件夹下都内置了一个__init__.py的文件,使其变成一个可互相调用的模块!

为了区别app目录和RealProject目录,我们将分别称起名为应用目录(app) , 项目目录(RealProject) ,在以后的教程中出现对应的字眼请自行甄别和区分!

在app的同级我们创建一个 RealProject 的目录,并分别在其内部创建 __init__.py 、 settings.py 、 wsgi.py 三个文件, 目录结构如下:

最后,我们将创建一个manage.py入口文件作为我们整个项目的入口,最后我们只需要运行该文件即可启动我们的项目!

最后,我们完整的目录结构如下所示:

熟悉django的同学肯定会对这个目录结构不会陌生,本目录结构本身也就是参照django的目录结构来构造!

import os

config="""

import os

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

class Config:

SECRET_KEY ='hard to guess string'

SQLALCHEMY_COMMIT_ON_TEARDOWN = True

FLASKY_MAIL_SUBJECT_PREFIX = '[Flasktest]'

FLASKY_MAIL_SENDER = ' [email protected] '

FLASKY_ADMIN = 'huangat'

@staticmethod

def init_app(app):

pass

class DevelopmentConfig(Config):

DEBUG = True

MAIL_SERVER = 'mail.163.com'

MAIL_PORT = 587

MAIL_USE_TLS = True

MAIL_USERNAME = os.environ.get('13285921108')

MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')

SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')

class TestingConfig(Config):

TESTING = True

SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-test.sqlite')

class ProductionConfig(Config):

SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')

config = {

'development': DevelopmentConfig,

'testing': TestingConfig,

'production': ProductionConfig,

'default': DevelopmentConfig

}

"""

manage="""

import os

from app import create_app, db

from app.models import User, Role

from flask_script import Manager, Shell

from flask_migrate import Migrate, MigrateCommand

app = create_app('default')

manager = Manager(app)

migrate = Migrate(app, db)

def make_shell_context():

return dict(app=app, db=db, User=User, Role=Role)

manager.add_command("shell", Shell(make_context=make_shell_context))

manager.add_command('db', MigrateCommand)

if name == ' main ':

manager.run()

"""

models="""

class User:

pass

class Role:

pass

"""

email="""

from threading import Thread

from email import charset

from flask_mail import Message

from flask import render_template

from flask import current_app# 这样就不用使用from manager import app

from . import mail

charset.add_charset('utf-8', charset.SHORTEST, charset.BASE64, 'utf-8')

def send_async_mail(app, msg):

with app.app_context():

mail.send(msg)

def send_mail(receiver, subject, template, **kw):

app = current_app._get_current_object()

msg = Message(subject=subject, sender=app.config[

'FLASKY_MAIL_SENDER'], recipients=[receiver], charset='utf-8')

msg.body = render_template(template + '.txt', **kw)

msg.html = render_template(template + '.html', **kw)

thr = Thread(target=send_async_mail, args=[app, msg])

thr.start()

return thr

"""

init="""

from os import path

from flask import Flask, request

from flask_bootstrap import Bootstrap

from flask_sqlalchemy import SQLAlchemy

from flask_login import LoginManager

from flask_mail import Mail

from flask_moment import Moment

from werkzeug.routing import BaseConverter

from config import config

class RegexConverter(BaseConverter):

bootstrap = Bootstrap()

db = SQLAlchemy()

login_manager = LoginManager()

mail = Mail()

moment = Moment()

login_manager.session_protection = 'strong'

login_manager.login_view = 'auth.login' # login_view设置登陆页面的端点

basedir = path.abspath(path.dirname( file ))

def create_app(config_name):

app = Flask( name )

app.config.from_object(config[config_name])

config[config_name].init_app(app)

"""

maininit="""

from flask import Blueprint

main = Blueprint('main', name )

from . import views, errors

"""

errors="""

from flask import render_template

from . import main

@main.app_errorhandler(404)

def page_not_found(e):

return render_template('404.html'), 404

@main.app_errorhandler(500)

def internal_server_error(e):

return render_template('500.html'), 500

"""

forms="""

class NameForm:

pass

"""

views="""

from datetime import datetime

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():

# ...

return redirect(url_for('main.index'))

return render_template('index.html',form=form, name=session.get('name'),known=session.get('known', False),current_time=datetime.utcnow())

"""

def main():

os.mkdir("app")

os.mkdir("app\main")

os.mkdir("app\static")

os.mkdir("app\templates")

os.mknod("app\templates\404.html")

os.mknod("app\templates\500.html")

os.mknod("app\templates\index.html")

os.mkdir("tests")

os.mkdir("venv")

os.mkdir("migrations")

os.mknod("requirements.txt")

os.mknod("tests_ init .py")

with open("config.py","w") as f:

f.write(config)

with open("manage.py","w") as f:

f.write(manage)

with open("app\models.py","w") as f:

f.write(models)

with open("app\email.py","w") as f:

f.write(email)

with open("app_ init .py","w") as f:

f.write(init)

with open("app\main_ init _.py","w") as f:

f.write(maininit)

with open("app\main\errors.py","w") as f:

f.write(errors)

with open("app\main\forms.py","w") as f:

f.write(forms)

with open("app\main\views.py","w") as f:

f.write(views)

main()

1、首先了解什么是 restful 架构?

rest :representational state transfer表现层状态转化

资源 :网络上的一个实体,或者说一个具体的信息。每种资源对应一个特定的URI,要获取这个资源,就是访问这个URI就可以

表现层 :representation 把资源呈现出来的形式,叫做表现层,在HTTP请求的头信息中用Accept和Content-Type字段指定,是对“表现层”的裤升描述

状态转化 :客户端想要 *** 作服务器,必须通过某种手段,让服务器发生状态转化,有 GET 、 POST 、 PUT 、 DELETE 四种方式,其中 GET 是用来获取资源, POST 是用来新建资源(也可以进行更新资源), PUT 用来更新资源, DELETE 用来删除资源

所以restful架构是:

1)每一个URI代表一个资源;

2)客户端和服务器之间,传递这种资源的某种表现层;

3)客户端通过四个HTTP动词,对服务器端资源进行 *** 作,实现“表现层状态转化”;

误区:最常见的一种设计错误,就是URI中包含动词。因为“资源”表示一种实体,所以应该是名词,URI不应该有动词,动词应该放到HTTP协议中

2、Flask-RESTful基本请求

其中一个接口有两种请求方式,一个是get,另一个是post。

get返回USER_LIST这个json数据;

post需要传一个参数,然后返回整个USER_LIST,请求一次post方法就会多添加一次数据,如果post请求中找不到name字段,则返回“400 Bad Request”错误;

由于类UserList没有定义put()和delete()函数,所以在”PUT”或”DELETE”请求时会返回”405 Method Not Allowed”世缺错误。

其中在postman中是这么胡返老进行传递的

GET请求

POST请求

另外,路由支持多个路径,比如:

访问userlist和users两个路径的效果完全一样

3、带参数的请求

上面的例子中我们都是针对USER_LIST这个列表的,如果我们需要针对具体的user进行 *** 作呢,就需要传递具体的user_id了,这时候,我们就需要路由支持带参数。

在User类的get(),post(),put()等成员函数中,记得加上参数user_id来获取传入的变量值

4、参数解析

在“POST”和“PUT”请求中,直接访问form表单并验证的工作有些麻烦,Flask-RESTful提供了 reqparse库来简化,可以通过 parser.add_argument() 方法来定义form表单字段,并指定其类型,然后在put或者post函数中调用 parser.parse_args() 来获取表单内容,并返回一个字典,该字典就包含表单的内容。 parser.parse_args() 方法会自动验证数据类型,返回400错误,还可以添加strict参数,如 parser.parse_args(strict=True) ,此时出现为定义的参数,也会返回400错误


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/8150845.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存