首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Flask了解一下

Flask是Python的轻量级Web后端框架,所谓轻量级——without orm,without templates language,without login manage,without db session manage,without admin...所以你可能要在一些方案中去选择你要的东西.

我把Web后端开发简单分为以下几步:

0. 数据库表设计;

路由设计;

HTML/JS/CSS开发;

后端表单数据校验及数据函数设计;

视图实现;

0.数据库表设计:)

根据需求设计数据表,定义清楚表字段名、字段类型、字段默认值、字段限制,表与表的关联(字段注释很重要),这里ORM选用SqlAlchemy,会话管理flak-sqlalchemy-session:

fromsqlalchemyimportString

fromsqlalchemyimportColumn

fromsqlalchemyimportDateTime

fromsqlalchemyimportInteger

fromcommons.funtionsimportget_now

fromdb.sqlite_engineimportBase

fromdb.sqlite_engineimportengine

classExample(Base):

__tablename__ ='example'

STATUS_ACTIVE =1

STATUS_BLOCK =

STATUS =

# id

id = Column(Integer,primary_key=True)

# 版本

version = Column(Integer,default=1)

# 用户名

name = Column(String(16),nullable=False)

# 邮箱

email = Column(String(64),nullable=False,unique=True)

# 创建时间

create_time = Column(DateTime,default=get_now())

# 状态

status = Column(Integer,default=STATUS_BLOCK)

基本数据类型Interger\String\DateTime\Text\Boolean\Float,超长文本LONGTEXT可能会用到。

---sqlalchemy操作数据---

查询

# 简单查询

# 查询冻结状态

query = current_session.query(Example).\

filter_by(status=Example.STATUS_BLOCK)

# 第1条记录

row = query.first()

# 所有记录

rows = query.all()

# 复杂查询

# 邮箱含'shenweiwei'并且状态激活

query = current_session.query(Example).\

filter(Example.email.contains('shenweiwei')).\

filter(Example.status == Example.STATUS_ACTIVE)

# 第1条记录

row = query.first()

# 所有记录

rows = query.all()

添加

更新

删除

1.路由设计:)

blueprint(蓝图)是flask用于组织路由/项目结构的模块,类似于Django的app,你可以在app里定义该app的相关路由,blueprint与之相似。当使用blueprint时,路由的标识将会添加上路由所在blueprint名作为前缀:bp_meet.index。

对于C(create)U(update)R(retrieve)D(delete),我们可以定义项目路由规范,例如统一的路由格式module/operate[/id],operate是(create,update,retrieve,delete)的元素,往往我们需要扩展operates,加入restart,stop,start等一系列操作。下面是定义一条新增应用的路由:

@bp_application.route('/application/add',methods=['POST','GET'],

endpoint='add')

@login_required

defapplication_add():

"""应用创建"""

pass

2.HTML/JS/CSS开发:)

HTML表单内容是由数据库表(数据)和路由(URL)来确定的,表单字段名务必与数据库表字段名保持一直!!!以便表单数据格式化直接添加/更新到数据库,不一致也没关系啦,不炸毛就好。

当前主机名

value="{{host_name}}">

主机名*

value="{%ifrow%}{{row.name}}{%endif%}"placeholder="必填"required>

平台名*

value="{%ifrow%}{{row.name_}}{%endif%}"placeholder="必填"required>

服务器地址*

value="{%ifrow%}{{row.server}}{%endif%}"placeholder="http(s)://ip:port"required>

提交

刷新页面的话,js里form.submit()提交数据:

只刷新数据的话,js里ajax放form.serializeArray()提交数据:

$.ajax({

cache:false,

type:'post',

url:'',

data: form.serializeArray(),

async:true,

success:function(resp) {

if(resp.status) {

window.location.href ='/sql/index';

}else{

alert(resp.message);

}

}

});

3.后端表单数据校验及数据函数设计:)

WTForms作为后端数据校验模块,除了字段内定义的校验器外,还可以定义validate_field(form, field)函数自定义field字段的校验,常用于复杂校验,如数据库查询校验,多字段关联校验。

form.validate() 检查所有字段的校验器,通过返回True,不通过则在form.errors里存放错误信息。

fromflask_sqlalchemy_sessionimportcurrent_session

fromwtformsimportStringField

fromwtformsimportIntegerField

fromwtformsimportvalidators

fromwtformsimportValidationError

fromcommons.base_formimportBaseForm

frombusiness.example.tablesimportExample

classIdVersion(BaseForm):

"""Id Version基类"""

id = IntegerField('id',

[validators.required(message='id is required.')])

version = IntegerField('version',

[validators.required(message='version is required.')])

defvalidate_id(self,_):

"""校验id-version"""

class_ =self.__class__.target

ifcurrent_session.query(class_).\

filter_by(id=self.id.data,

version=self.version.data).first():

raiseValidationError('record is not exist.')

classExampleBaseForm(BaseForm):

"""Example基类"""

name = StringField('name',

[validators.input_required(message='name is required.'),

validators.length(max=16,message='name_max_length=16')])

email = StringField('email',

[validators.input_required(message='email is required.'),

validators.length(max=64,message='email_max_length=64')])

status = IntegerField('status',[validators.optional()])

defdata_parser(self):

data =self.data

data.pop('csrf_token', None)

returndata

classExampleAddForm(ExampleBaseForm):

"""添加Example"""

@staticmethod

defvalidate_email(_,field):

"""添加时 校验邮箱"""

row = current_session.query(Example).filter_by(email=field.data).first()

ifrow:

raiseValidationError('user email existed: %s'% field.data)

classExampleEditForm(ExampleBaseForm,IdVersion):

"""修改Example"""

target = Example

@staticmethod

defvalidate_email(form,field):

"""修改时 校验邮箱"""

row = current_session.query(Example).filter_by(email=field.data).first()

ifrowandrow != form.id.data:

raiseValidationError('user email existed: %s'% field.data)

上面创建了四个Form类,IdVersion用于所有表单修改/删除数据时,记录版本的校验;ExampleBaseForm用于被新增/修改Form继承使用,ExampleAddForm是新增数据Form,ExampleEditForm是修改Form,ExampleEditForm与ExampleAddForm会在部分字段的校验上有差异,例如上面的validate_email实现是不一样的,删除Form可参考IdVersion。

最近发现Django和Flask在Form处理上有着一些差异,有一点,Django实例化的form具有所有提交的数据字段,不管这些字段在Form类中是否有定义,而Flask实例化的form只具有Form中类的字段。Django的这种“随和”性质让一些人的代码越加恣意妄为:新加字段不写到Form类里,不校验,反正不会报错...

往往由表单提交到后端的数据不能直接保存到数据库,需要对数据再处理,比如添加操作人,这时,我会给form类添加一个data_parser()的函数,专门处理数据,返回供新增/更新数据库记录的dict数据:

classExampleBaseForm(BaseForm):

"""校验"""

pass

4.视图实现:)

视图函数是最后一步,可能有些新人上来就是先写这个,其实不然,0到3是基石,当然第4步是最重要的业务实现部分,这里只是简单的介绍了Flask下的web开发过程,以供参考。

@bp_application.route('/application/add',methods=['POST','GET'],

endpoint='add')

@login_required

defapplication_add():

"""应用创建"""

ifrequest.method =='GET':

returnrender_template('/application/application_add.html',**locals())

form = ApplicationAddForm()

if notform.validate():

returnjsonify({'status':False,'errors': form.errors.values()})

app = form.data_parser()

row = Application(**app)

current_session.add(row)

current_session.commit()

returnjsonify({'status':True,'message':'add success.'})

一次流畅的开发是0到4一气呵成,而不是在4的时候不断修改0到3.

references:

flaskhttp://docs.jinkan.org/docs/flask/tutorial/index.html#tutorial

sqlalchemyhttp://docs.sqlalchemy.org/en/latest/core/tutorial.html

flask_sqlalchemy_sessionhttp://flask-sqlalchemy-session.readthedocs.io/en/v1.1/

wtformshttps://wtforms.readthedocs.io/en/stable/#

flask-wtfhttp://flask-wtf.readthedocs.io/en/stable/quickstart.html

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180607G23C1200?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券