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項目目錄維護;