1:重量级web框架,功能齐全,提供一站式解决的思路,能让开发者不用在选择应用上花费大量时间;
2:自带ORM(Object-Relational Mapping 对象关联映射)和模板引擎,支持JinJa等非官方模板引擎,灵活度不高;
3:自带ORM使Django和关系型数据库耦合度太高,若是要使用非关系型数据库,须要使用第三方库;
4:自带数据库管理app;
5:成熟、稳定、开发效率高、相对于Flask,Django的总体封闭性比较好,适合作企业级网站的开发;
6:python web框架的先驱,第三方库丰富;
7:上手容易,开发文档详细、完善、资料丰富;
1:轻量级web框架,只有一个内核,默认依赖两个外部库:Jinja2 模板引擎和 Werkzeug WSGI 工具集,自由,灵活,可扩展性强,开发者能够根据需求本身造轮子;
2:适用于作小型网站以及web服务的API,开发大型网站无压力,架构需自行设计;
3:与关系型数据库结合不弱于Django,而与非关系型数据库的结合远远优于Django;
http://www.cnblogs.com/zhaopanpan/articles/9457343.htmlhtml
问题一:flask和django的区别: 对于django来讲,内部组件特别多,自身功能强大,有点大而全,而flask,内置组件不多,可是它的第三方组件不少,扩展性强,有点短小精悍,而它们之间也有类似之处, 由于它们两个框架都没有写sockte,都是基于wsgi协议作的,在此以外,flask框架中的上下文管理较为耀眼。 相同点:它们两个框架都没有写sockte,都是基于wsgi协议作的 请求相关数据传递的方式不一样:django:经过传递request参数取值 flask:见问题二 组件不一样:django组件多 flask组件少,第三方组件丰富 问题1.1: flask上下文管理: 简单来讲,falsk上下文管理能够分为三个阶段: 1、请求进来时,将请求相关的数据放入上下问管理中 2、在视图函数中,要去上下文管理中取值 3、请求响应,要将上下文管理中的数据清除 详细点来讲: 1、请求刚进来,将request,session封装在RequestContext类中,app,g封装在AppContext类中,并经过LocalStack将requestcontext和appcontext放入Local类中 二、视图函数中,经过localproxy--->偏函数--->localstack--->local取值 3、请求相应时,先执行save.session()再各自执行pop(),将local中的数据清除 问题1.2 flask第三方组件 flask: -flask-session 默认放入cookie,能够放入redis -flask-redis -flask-migrate -flask-script -blinker 信号 公共: DBUtils 数据库链接池 wtforms 表单验证+生成HTML标签 sqlalchemy 自定义:Auth 参考falsk-login 问题二:Flask中的session是何时建立,何时销毁的? 当请求进来时,会将requset和session封装为一个RequestContext对象,经过LocalStack将RequestContext放入到Local对象中,由于 请求第一次来session是空值,因此执行open_session,给session(uuid4())赋值,再经过视图函数处理,请求响应时执行save.session,将签名session写入cookie中,再讲Local中的数值pop掉。 问题三:flask中一共有几个LocalStack和Local对象 两个LocalStack,两个Local request、session共同用一个LocalStack和Local g、app共同用一个Localstack和Local 问题四: 为何把请求放到RequestContext中: 由于request和session都是在视图中操做频繁的数据,也是用户请求须要用的数据,将request和session封装在RequestContext中top,pop一次就能够完成,而单独不封装在一块儿就会屡次操做, ctx = RequestContext(request,session) 问题五:local做用 -保存 请求上下文对象和app上下文对象 -localstack的源码与threading.local(线程处理)做用类似,不一样之处是Local是经过greenlet(协程)获取惟一标识,粒度更细 问题六:Localstack做用 2、将local对象中的数据维护成一个栈【ctx,ctx】(先进后出) { “协程或线程的惟一标识”: { stack:[ctx,ctx,ctx,] } } 为何维护成一个栈? 当是web应用时:不论是单线程仍是多线程,栈中只有一个数据 - 服务端单线程: { 111:{stack: [ctx, ]} } - 服务端多线程: { 111:{stack: [ctx, ]} 112:{stack: [ctx, ]} } 离线脚本:能够在栈中放入多个数据 with app01.app_context(): print(current_app) with app02.app_context(): print(current_app) print(current_app) 问题七:什么是g? g 至关于一次请求的全局变量,当请求进来时将g和current_app封装为一个APPContext类,在经过LocalStack将Appcontext放入Local中,取值时经过偏函数,LocalStack、loca l中取值,响应时将local中的g数据删除: 问题八:怎么获取Session/g/current_app/request 经过 、偏函数(lookup_req_object)、Localstack、Local取值 问题九: 技术点: - 反射 (LocalProxy()) - 面向对象,封装:RequestContext - 线程(threading.local) - 笔试:本身写一个类+列表 实现栈。(LocalStack) 问题十:python基本哪些内容比较重要: 1、反射 -CBV -django配置文件 -wtforms中的Form()示例化中 将"_fields中的数据封装到From类中" 2、装饰器 (迭代器,生成器) -flask:路由、装饰器 -认证 -csrf 3、面向对象 -继承、封装、多态(简单描述) -双下划线: __mro__ wtform中 FormMeta中继承类的优先级 __dict__ __new__ ,实例化可是没有给当前对象 wtforms,字段实例化时返回:不是StringField,而是UnboundField rest frawork many=Turn 中的序列化 __call__ flask 请求的入口app.run() 字段生成标签时:字段.__str__ => 字段.__call__ => 插件.__call__ __iter__ 循环对象是,自定义__iter__ wtforms中BaseForm中循环全部字段时定义了__iter__ metaclass - 做用:用于指定当前类使用哪一个类来建立 - 场景:在类建立以前定制操做 示例:wtforms中,对字段进行排序。
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-21 16:31 # File : 3.metaclass.py # Author : 天晴天朗 # Email : tqtl@tqtl.org # 建立类的两种方式; # 方式一: class Foo(object): CITY = 'BJ' def func(self, x): return x + 1 # 方式二: def func(self, x): return x + 1 # Foo1 = type('Foo1', (object,), {'CITY': 'BJ', 'func': func}) # 另一种形式: Foo2 = type('Foo', (object,), {'CITY': 'BJ', 'func': lambda self, x: x + 1}) # 二、类由自定义type建立; class Foo3(object, metaclass=type): # 当前类由type类建立; # __metaclass__ = type# Python2的建立方式; CITY = 'BJ' def func(self, x): return x + 1 class MyType(type): def __init__(self, *args, **kwargs): print('建立类以前') super(MyType, self).__init__(*args, **kwargs) print('建立类以后') class Foo4(object, metaclass=MyType): CITY = 'BJ' def func(self, x): return x + 1 print(Foo4) """ 一、类由type建立,metaclass能够指定当前类由哪个类建立; """ class MyType1(type): def __init__(self, *args, **kwargs): print('建立类以前') super(MyType1, self).__init__(*args, **kwargs) print('建立类以后') class Foo1(object, metaclass=MyType1): CITY = 'BJ' def func(self, x): return x + 1 class Bar(Foo): pass """ 小结: 一、默认类由type实例化建立; 二、某个类指定metaclass = MyType,那么当前类的全部派生类都因为MyType建立; 三、实例化对象: -type.__init__ -type.__call__ -类名.__new__ -类名.__init__ """
# 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中; meta类读取到cls._wtforms_meta中 2. 执行构造方法 a. 循环cls._unbound_fields中的字段,并执行字段的bind方法,而后将返回值添加到 self._fields[name] 中。 即: _fields = { name: wtforms.fields.core.StringField(), } PS:因为字段中的__new__方法,实例化时:name = simple.StringField(label='用户名'),建立的是UnboundField(cls, *args, **kwargs),当执行完bind以后,才变成执行 wtforms.fields.core.StringField() b. 循环_fields,为对象设置属性 for name, field in iteritems(self._fields): # Set all the fields to attributes so that they obscure the class # attributes with the same names. setattr(self, name, field) c. 执行process,为字段设置默认值:self.process(formdata, obj, data=data, **kwargs) 优先级:obj,data,formdata; 再循环执行每一个字段的process方法,为每一个字段设置值: for name, field, in iteritems(self._fields): if obj is not None and hasattr(obj, name): field.process(formdata, getattr(obj, name)) elif name in kwargs: field.process(formdata, kwargs[name]) else: field.process(formdata) 执行每一个字段的process方法,为字段的data和字段的raw_data赋值 def process(self, formdata, data=unset_value): self.process_errors = [] if data is unset_value: try: data = self.default() except TypeError: data = self.default self.object_data = data try: self.process_data(data) except ValueError as e: self.process_errors.append(e.args[0]) if formdata: try: if self.name in formdata: self.raw_data = formdata.getlist(self.name) else: self.raw_data = [] self.process_formdata(self.raw_data) except ValueError as e: self.process_errors.append(e.args[0]) try: for filter in self.filters: self.data = filter(self.data) except ValueError as e: self.process_errors.append(e.args[0]) d. 页面上执行print(form.name) 时,打印标签 由于执行了: 字段的 __str__ 方法 字符的 __call__ 方法 self.meta.render_field(self, kwargs) def render_field(self, field, render_kw): other_kw = getattr(field, 'render_kw', None) if other_kw is not None: render_kw = dict(other_kw, **render_kw) return field.widget(field, **render_kw) 执行字段的插件对象的 __call__ 方法,返回标签字符串
#!/usr/bin/env python # -*- coding:utf-8 -*- from flask import Flask, render_template, request, redirect from wtforms import Form from wtforms.fields import core from wtforms.fields import html5 from wtforms.fields import simple from wtforms import validators from wtforms import widgets app = Flask(__name__, template_folder='templates') app.debug = True class LoginForm(Form): name = simple.StringField( label='用户名', validators=[ validators.DataRequired(message='用户名不能为空.'), validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d') ], widget=widgets.TextInput(), render_kw={'class': 'form-control'} ) pwd = simple.PasswordField( label='密码', validators=[ validators.DataRequired(message='密码不能为空.'), validators.Length(min=8, message='用户名长度必须大于%(min)d'), validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}", message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符') ], widget=widgets.PasswordInput(), render_kw={'class': 'form-control'} ) @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'GET': form = LoginForm() return render_template('login.html', form=form) else: form = LoginForm(formdata=request.form) if form.validate(): print('用户提交数据经过格式验证,提交的值为:', form.data) else: print(form.errors) return render_template('login.html', form=form) if __name__ == '__main__': app.run() app.py
a. 执行form的validate方法,获取钩子方法 def validate(self): extra = {} for name in self._fields: inline = getattr(self.__class__, 'validate_%s' % name, None) if inline is not None: extra[name] = [inline] return super(Form, self).validate(extra) b. 循环每个字段,执行字段的 validate 方法进行校验(参数传递了钩子函数) def validate(self, extra_validators=None): self._errors = None success = True for name, field in iteritems(self._fields): if extra_validators is not None and name in extra_validators: extra = extra_validators[name] else: extra = tuple() if not field.validate(self, extra): success = False return success c. 每一个字段进行验证时候 字段的pre_validate 【预留的扩展】 字段的_run_validation_chain,对正则和字段的钩子函数进行校验 字段的post_validate【预留的扩展】
关系-对象-映射(Object-Object Relational Mapping);html5
当有了对应关系后,再也不须要编写SQL语句,取而代之是操做:类、对象;python
8.2.1 ORM;mysql
8.2.2 SQL;web
8.2.3 DB First(已经使用原生SQL开发,根据数据库的表生成类);面试
8.2.4 Code First(ORM是CodeFirst,根据类建立数据表);redis
8.2.5 ORM是如何实现的?内置解析器实现;经过对象和类转化成字符换;sql
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 09:54 # File : 1.ORM.py # Author : 天晴天朗 # Email : tqtl@tqtl.org "" """ SQLAlchemy插入数据操做; """ import models #from sqlalchemy.ext.declarative import declarative_base #from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index from sqlalchemy.orm import sessionmaker, relationship from sqlalchemy import create_engine engine = create_engine("mysql+pymysql://root:Tqtl911!@%*)@mysql.cuixiaozhao.com:3306/flask_session", max_overflow=5) Session = sessionmaker(bind=engine) session = Session() obj1 = models.Users(name="cuixiaozhao", extra="cxz") obj2 = models.Users(name="cuixiaozhao", extra="cxz") session.add(obj1) session.add(obj2) session.commit()
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 09:54 # File : models.py # Author : 天晴天朗 # Email : tqtl@tqtl.org "" """ 一、安装pip3 install sqlalchemy ; 二、依赖于pymysql进行数据库链接; 三、并不支持修改表结构,仅支持在数据库修改字段后,再从新在此处修改; """ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, UniqueConstraint, Index from sqlalchemy import create_engine Base = declarative_base() # 建立数据表; class Users(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(32)) extra = Column(String(16)) # __table_args = ( # UniqueConstraint('id', 'name', name='uix_id_name'), # Index('ix_id_name', 'name', 'extra') # ) # 数据库链接相关; # engine = create_engine("mysql+pymysql://root:Tqtl911!@%*)@mysql.cuixiaozhao.com/flask_session?charset=utf8") # Base.metadata.create_all(engine) # 删除表; # Base.metadata.drop_all(engine) # 向表中插入数据; def init_db(): # 数据库链接相关; engine = create_engine("mysql+pymysql://root:Tqtl913421411!@%*)@123.321.com:3306/flask_session?charset=utf8") # 建立表; Base.metadata.create_all(engine) def drop_db(): # 数据库链接相关; engine = create_engine("mysql+pymysql://root:Tqtl911!@%*4321432)@123.321.com:3306/flask_session?charset=utf8") # 删除表; Base.metadata.drop_all(engine) if __name__ == '__main__': init_db() # drop_db()
SQLAlchemy自己没法操做数据库,其必须以来pymsql等第三方插件,Dialect用于和数据API进行交流,根据配置文件的不一样调用不一样的数据库API,从而实现对数据库的操做,如:数据库
MySQL-Python mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> pymysql mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] MySQL-Connector mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> cx_Oracle oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] 更多详见:http://docs.sqlalchemy.org/en/latest/dialects/index.html
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 11:05 # File : 3.执行原生SQL.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from sqlalchemy import create_engine engine = create_engine("mysql+pymysql://root:@flask_session123456mysql.cuixiaozhao.com:3306/", max_overflow=5) # 执行SQL cur = engine.execute( "INSERT INTO hosts (host, color_id) VALUES ('1.1.1.22', 3)" ) # 新插入行自增ID cur.lastrowid # 执行SQL cur = engine.execute( "INSERT INTO hosts (host, color_id) VALUES(%s, %s)", [('1.1.1.22', 3), ('1.1.1.221', 3), ] ) # 执行SQL cur = engine.execute( "INSERT INTO hosts (host, color_id) VALUES (%(host)s, %(color_id)s)", host='1.1.1.99', color_id=3 ) # 执行SQL cur = engine.execute('select * from hosts') # 获取第一行数据 cur.fetchone() # 获取第n行数据 cur.fetchmany(3) # 获取全部数据 cur.fetchall()
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 15:14 # File : 2.单表的增长操做.py # Author : 天晴天朗 # Email : tqtl@tqtl.org import models from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine engine = create_engine("mysql+pymysql://fda!fda%*)@mysql.dfa.com:3306/flask_session?charset=utf8") xxxx = sessionmaker(bind=engine) session = xxxx() # 单条记录增长 # obj = models.Classes(name = "全栈1期") # session.add(obj) # 多条记录增长; objs = [ # models.Classes(name = '全栈2期'), models.Classes(name='全栈3期'), models.Classes(name='全栈4期'), models.Classes(name='全栈5期'), ] session.add_all(objs) session.commit() session.close()
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 15:29 # File : 3.单表的查询操做.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine import models engine = create_engine("mysql+pymysql://fdafda!@%*)@fa.fda.com:3306/flask_session?charset=utf8") maker = sessionmaker(bind=engine) session = maker() # 查询; result = session.query(models.Classes).all() # print(result)#[<models.Classes object at 0x10dcb2358>, <models.Classes object at 0x10dcb23c8>, <models.Classes object at 0x10dcb2438>, <models.Classes object at 0x10dcb24a8>, <models.Classes object at 0x10dcb2518>] for item in result: print(item.id, item.name) session.commit() session.close()
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 15:33 # File : 4.单表的删除操做.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine import models engine = create_engine("mysql+pymysql://ffdfdaf!@%*)@fda.cuifdasxiaozhao.com:3306/flask_session?charset=utf8") maker = sessionmaker(engine) session = maker() # 删除 result = session.query(models.Classes).filter(models.Classes.id > 13).delete() session.commit() session.close()
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 15:38 # File : 5.单表的修改操做.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine import models engine = create_engine("mysql+pymysql://root:Tfdasfda1!@%*)@123.45.67.89:3306/flask_session?charset=utf8") maker = sessionmaker(engine) session = maker() # 更新操做;˚ session.query(models.Classes).filter(models.Classes.id > 0).update({models.Classes.name: models.Classes.name + "999"}, synchronize_session=False) # 尾部的参数决定了是进行字符串操做仍是数学运算操做; session.commit() session.close()
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 15:38 # File : 5.单表的修改操做.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine import models engine = create_engine("mysql+pymysql://root:Tqtl911!@%*)@mysql.cuixiaozhao.com:3306/flask_session?charset=utf8") maker = sessionmaker(engine) session = maker() # 更新操做;˚ session.query(models.Classes).filter(models.Classes.id > 0).update({models.Classes.name: models.Classes.name + "999"}, synchronize_session=False) # 尾部的参数决定了是进行字符串操做仍是数学运算操做; session.commit() session.close()
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 16:15 # File : 7.练习.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine, text import models engine = create_engine("mysql+pymysql://root:Tqtl911!@%*)@mysql.cuixiaozhao.com:3306/flask_session?charset=utf8") maker = sessionmaker(bind=engine) session = maker() obj = models.Student(username='崔晓丝', password='123456', class_id=2) session.add(obj) # 在学生表中找到崔晓丝; obj1 = session.query(models.Student).filter(models.Student.username == '崔晓丝').first() print(obj1) # <models.Student object at 0x108762a90> # 找到全部学生; # 一、LOW B查询方式; # objs = session.query(models.Student).all() # for obj in objs: # cls_obj = session.query(models.Classes).filter(models.Classes.id ==obj.class_id).first() # print(obj.id,obj.username,obj.class_id,cls_obj.name) # 二、主动连表操做; objs = session.query(models.Student.id, models.Student.username, models.Classes.name).join(models.Classes, isouter=True).all() print(objs) # 三、relationship引入; objs2 = session.query(models.Student).all() for item in objs2: print(item.id,item.username,item.class_id,item.cls.name) session.commit() session.close() # 四、全栈2期全部的学生 obj3 = session.query(models.Classes).filter(models.Classes.name =="全栈2期999").first() student_list = obj3.stus for i in student_list: print(i.id,i.username) print("全栈2期全部的学生",student_list)
# 条件 ret = session.query(Users).filter_by(name='alex').all() ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all() ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all() ret = session.query(Users).filter(Users.id.in_([1,3,4])).all() ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all() ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all() from sqlalchemy import and_, or_ ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all() ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all() ret = session.query(Users).filter( or_( Users.id < 2, and_(Users.name == 'eric', Users.id > 3), Users.extra != "" )).all() # 通配符 ret = session.query(Users).filter(Users.name.like('e%')).all() ret = session.query(Users).filter(~Users.name.like('e%')).all() # 限制 ret = session.query(Users)[1:2] # 排序 ret = session.query(Users).order_by(Users.name.desc()).all() ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all() # 分组 from sqlalchemy.sql import func ret = session.query(Users).group_by(Users.extra).all() ret = session.query( func.max(Users.id), func.sum(Users.id), func.min(Users.id)).group_by(Users.name).all() ret = session.query( func.max(Users.id), func.sum(Users.id), func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all() # 连表 ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all() ret = session.query(Person).join(Favor).all() ret = session.query(Person).join(Favor, isouter=True).all() # 组合 q1 = session.query(Users.name).filter(Users.id > 2) q2 = session.query(Favor.caption).filter(Favor.nid < 2) ret = q1.union(q2).all() q1 = session.query(Users.name).filter(Users.id > 2) q2 = session.query(Favor.caption).filter(Favor.nid < 2) ret = q1.union_all(q2).all() 经常使用操做
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: SQLALchemy # Software: PyCharm # Time : 2018-09-22 19:10 # File : 1.总结.py # Author : 天晴天朗 # Email : tqtl@tqtl.org import models from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine engine = create_engine("mysql+pymysql://root:Tqtl911!@%*)@mysql.cuixiaozhao.com:3306/flask_session?charset=utf8") xxxx = sessionmaker(bind=engine) session = xxxx() session.add session.add_all() session.query(Users).all() session.query(Users.id, Users.name).filter(User.name == 'alex') session.query(Users.id, Users.name).filter_by(name='alex') session.query(Users.id, Users.name).filter_by(name='alex').filter() session.query(Users.id, Users.name).filter(User.name == 'alex').update({}, 字符串) session.query(Users.id, Users.name).filter(User.name == 'alex').update({}, 计算) session.query(Users.id, Users.name).filter(Users.name == 'alex').delete()
-函数的参数传递的是什么?django
-def func(a,b=[]):pass
-lambda 表达式
-列表生成式
-生成器表达式
-常见的内置函数:map、reduce、filter、zip、instance、type
2.6.1 WTForms做用?
2.6.2 WTForms涉及到的做用点?哪里用到了?
2.6.3 ORM和原生SQL比较?
2.6.4 你用过的ORM框架有哪些?Django ORM SQLAlchemy,全部的语言都有ORM;
2.6.5 DBFirst、CodeFIrst;
2.6.6 SQLAlchemy自带数据库链接池;
2.1.1 编译型和解释性的区别;
2.1.2 解释型:Python、PHP
2.1.3 编译型:C 、C++
2.1.4 混合型:Java
2.2.1 简单易学;
2.2.2 生态圈比较强大;
2.2.3 发展趋势比较好,人工智能、数据分析;
2.2.4 还有不少...
常见内置函数-map reduce filter zip instance type
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: FullFlask # Software: PyCharm # Time : 2018-09-23 15:51 # File : manage.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from FullFlask import create_app from flask_script import Manager app = create_app() manager = Manager(app) @manager.command def custom(arg): print(arg) @manager.option('-n', '--name', dest='name') @manager.option('-u', '--url', dest='url') def cmd(name, url): """ 自定义命令: 执行:python manage.py cmd -n cuixiaozhao -u http://cuixiaozhao.com 执行:python manage.py cmd --name cuixiaozhao --url http://cuixiaozhao.com :param name: :param url: :return: """ print(name, url) if __name__ == '__main__': # app.run() manager.run()
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: FullFlask # Software: PyCharm # Time : 2018-09-23 15:54 # File : accounts.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from flask import blueprints from FullFlask import models ac = blueprints.Blueprint('ac', __name__) @ac.route('/login', methods=['GET', 'POST']) def login(): from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine engine = create_engine("mysql+pymysql://root:Tqtl911!@%*)@mysql.cuixiaozhao.com:3306/FullFlask?charset=utf8") maker = sessionmaker(bind=engine) session = maker() result = session.query(models.Users).all() session.close() print( result) # [<FullFlask.models.Users object at 0x106123c88>, <FullFlask.models.Users object at 0x106123dd8>, <FullFlask.models.Users object at 0x106123a90>, <FullFlask.models.Users object at 0x1061239e8>] return 'Login it.'
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: FullFlask # Software: PyCharm # Time : 2018-09-23 16:37 # File : settings.py # Author : 天晴天朗 # Email : tqtl@tqtl.org class BaseConfig(object): SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:Tqtl911!@%*)@mysql.cuixiaozhao.com:3306/FullFlask?charset=utf8" SQLALCHEMY_POOL_SIZE = 5 SQLALCHEMY_POOL_TIMEOUT = 30 SQLALCHEMY_POOL_RECYCLE = -1 # 追踪对象的修改而且发送信号; SQLALCHEMY_TRACK_MODIFICATIONS = False class ProductionConfig(BaseConfig): pass class DevelopmentConfig(BaseConfig): pass class TestConfig(BaseConfig): pass """ 小结: 一、flask-sqlalchemy的做用:将SQLAlchemy相关的全部功能都封装到db=flask_sqlalchemy.SQLAlchemy()对象中; -建立表; class Users( ): pass -操做表; db.session """
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: FullFlask # Software: PyCharm # Time : 2018-09-23 17:08 # File : drop_table.py # Author : 天晴天朗 # Email : tqtl@tqtl.org "" """ 一、Web运行时候,flask程序运行起来,用户经过浏览器访问; 二、离线脚本,即自定义的一个py文件+使用flask中定义好的功能; """ from FullFlask import db from FullFlask import create_app from FullFlask import models app = create_app() with app.app_context(): # db.drop_all() # db.create_all() data = db.session.query(models.Users).all() print(data)
本质就是对URL的分发和处理;
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: FullFlask # Software: PyCharm # Time : 2018-09-23 21:32 # File : 多app应用.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from flask import Flask from werkzeug.wsgi import DispatcherMiddleware from werkzeug.serving import run_simple app01 = Flask('app01') app02 = Flask('app02') dm = DispatcherMiddleware(app01, { '/app02': app02, }) if __name__ == '__main__': run_simple('localhost', 5000, dm)
# Core signals. For usage examples grep the source code or consult # the API documentation in docs/api.rst as well as docs/signals.rst template_rendered = _signals.signal('template-rendered') before_render_template = _signals.signal('before-render-template') request_started = _signals.signal('request-started') request_finished = _signals.signal('request-finished') request_tearing_down = _signals.signal('request-tearing-down') got_request_exception = _signals.signal('got-request-exception') appcontext_tearing_down = _signals.signal('appcontext-tearing-down') appcontext_pushed = _signals.signal('appcontext-pushed') appcontext_popped = _signals.signal('appcontext-popped') message_flashed = _signals.signal('message-flashed')
#!/usr/bin/python3 # -*- coding:utf-8 -*- # Project: FullFlask # Software: PyCharm # Time : 2018-09-23 21:48 # File : Flask-signal.py # Author : 天晴天朗 # Email : tqtl@tqtl.org from flask import Flask, signals app = Flask(__name__) def func1(*args, **kwargs): print('触发信号:request_started') def func2(*args, **kwargs): print('触发信号:request_started') signals.request_started.connect(func1) signals.appcontext_pushed.connect(func2) @app.route('/login') def login(): return 'Login' if __name__ == '__main__': app.run()
14.3.1 手写Flask内置HelloWorld!
14.3.2 Flask和其余框架的区别?
14.3.3 Flask内置组件:
14.3.4 Flask第三方组件:
14.3.5 公共组件:
14.3.6 自定义Flask组件:
14.3.7 上下文管理机制:
14.3.8 Flask项目目录维护;