zoukankan      html  css  js  c++  java
  • flask2

    flask2 & get方法

    -1 装饰器

    def war(func):
    	def inner(*args,**kwargs):
    		if session.get('username'):
            	ret = func(*args,**kwargs)
    			return ret
    	return inner
    
    @app.route('/detail')	
    @war		#执行inner --> func()   - return ret  war(detail)  --> inner
    def detail():
     	return ....
    

    -1.1 不同的函数用装饰器,抛出异常

    error: function mapping is overwriting an existing endpoint function :inner

    源码: def route(self,rule,**options)	#第一个参数app  /detail    {}
    
    	def decorator(f) :   f = def details
    		end  =  options.pop('end',None)			#None
    		
    		
    在代码    app.add_url_rule(rule,end,f,**options)# '/detail'  None   def detail  {}  	#本质上是执行这句话
    	if end is None:
    		end = _end_from_view_func(view_func)	#里面 return view_func.__name__ #return 'details'
    		
    		#assert 断言   view_func.__name__ is not None 
    					
    	options['end'] = end		#{}  -->  {'end':‘detail’}
    	methods = options.pop('methods',None)		#没有返回空
    	
    	if methods is None:
    		methods = getattr(view_func,'methods',None) or ('GET',)
    	
    	methods = set(item.upper() for item in methods)	#集合去重
    	
    	if view_func is not None: 
    		old_func = self.view_functions.get(end)	#v_f 所有的视图函数
    		if old_fun is not None and old_func! = view_func:
    			raise AssertionError()
    		self.view_functions[end] = view_func
    						#view_function = {'details':deatils}
    		
    2 新的op =  {'methods' : ['GET','get','Get']}		带过去
    
    
    	if old_fun is not None and old_func! = view_func: # 老innner的内存地址和新inner的内存地址   detail 和 deatils
    	
    	
    解决方法:(不会出现重名不同函数的现象)
    1
    if end is None:
    				end = option 
    给endpoints = 传参 不为None
    
    2  from  functools import  wraps 	#返回原来的函数名
    def war(func):			#装饰器
    	@wraps(func) 		#利用偏函数的原理
    		
    

    为多个视图函数增加同一个装饰器

    1 Flask 中的路由

    参数:

    ​ endpoint 映射路由-视图函数_name_ = ''(字符串)

    @	endpoint='loginasdf'
    def login():
    	print(url_for('loginasdf'))			#login
    

    ​ methods = []/() #--> 集合set(xxx.lower )

    ​ #当前视图函数支持的请求方法 405 请求方式不被允许 defaults = {'id':1} #默认参数 一旦默认参数存在,视图函数必须有一个形参去接收,形参变量名必须与defaults中的一致

    ​ strict_salshes = False/True #是否严格遵循路由匹配(默认是true)

    ​ redirect_to = '/login' #308(环境问题301有时) 永久重定向 不经过视图函数的(不浪费那块空间) (老页面新页面)

    ​ 动态参数路由

    ​ #分页

    ​ route('details/int:/int:/int:/')

    ​ print(page,page1,page2) #传参 (必须是定长的传三个)

    ​ route('details/int:/')

    ​ route('details/string:/') 什么都不写 默认string

    ​ #通过路由地址访问文件

    ​ /s1.py url地址

    ​ def detail(folder,filename) #folder 跨目录

    ​ #写url /template/xx.html(前面是。。/后面对应)

    ​ fp=os.path.join(folder,filename)

    ​ return send_file()

    2 .Flask中的配置

    1. 初始化配置
      app = Flask(_name_,template_folder='templatess',static_folder='statics',static_url_path='/static') #存放路径 /开头:路由地址

      static_folder='statics'   #静态文件存放路径	
      static_url_path='/static' #静态文件访问路径  - 默认/ + folder
      static_host = None,		  #访问这,去另一个主机去拿
      host_matching=False,	  #定义的是ip/域名 只能按定义的匹配	
      subdomain_matching=False, #car子域名www主域名
      	nginx 可以阻拦域名 子域名(替代分发)上两个
      
      
    2. config 对象配置

    app.config['DEBUG'] = True

    app.config #第三方组件 environment 都在这里

    DEBUG --- 编码阶段
    代码重启(大多数)日志输出级别很低(查错看到error:扔到数据库记上) (大量日志(银行)存到缓存(速度太快))
    页面种会显示错误 错误代码(没testing,关了debug,自动开启testing)

    TESTING --- 测试阶段 日志输出级别较高 不重启 无限接近线上环境

    "SECRET_KEY": None,		#不一样 可能加连个md5	
    			 SECRET_KEY = hashlib.md5(b'12352344553').hexdigest()
    SERVER_NAME				#相当于域名
    SESSION_COOKIE_NAME
    SESSION_COOKIE_DOMAIN	#在那个域名下配置
    SESSION_COOKIE_PATH 	#在那个个环境
    SESSION_COOKIE_HTTPONLY
    JSONIFY_MIMETYPE		#自己做反爬	(随便改的话下载的)
    
    make_config
    	default_config		
    		{'ENV','DEBUG':(不能在这里改)}
    
    app.default_config		#可以查询 忘了    
    
    <img src="/static/2.jpg">		#
    {#路由地址  不是静态文件访问的地址#}
    staic_floader = 'static'  
    

    app.config['TESTING'] = True

     * Debug mode: off
    127.0.0.1 - - [11/Jul/2019 11:01:01] "GET /statics/2.jpg HTTP/1.1" 404 -
    

    运维开发都是你,测试也是你的话

    那样,成长速度很快
    
    app.config['JSONIFY_MIMETYPE']  = '2534ijij/isjiga'
    @app.route('/bab')
    def bab():
        return {'k':1} #封装了 jsonify			#会下载
    

    from_object

    for key in dir(obj): 		#把每个变成字典
      if key.isupper():			
                    self[key] = getattr(obj, key)	#slef = config
    	...
    	config['DEBUG']  = True
                    		           		
    

    config 写的 都可以序列化
    s20 = 'NB'
    SESSION_TYPE = 'Redis'

    名言

    不要把时间浪费在路上 ----哪个名人

    3 flask 蓝图

    当成是 一个不能被run的flask对象
    作用:应用隔离,不用注销了

    serv --
    --users.py

    from flask import Blueprint
    
    #不能被 run的       一个flask 蓝图唯一个标识
    user = Blueprint('user',__name__)	# template_folder = 'serv/user'
    							   	# 都可以和flask对象差不多init封装
    @user.route('/get_user',methods=['GET','post'])	#大小写都行
    def get_user():
        return "I am Users Blueprint"
    

    蓝图没有 run , 因为没有config(run 基于 config)

    from flask import Flask
    from serv.users import user
    
    app = Flask(__name__)
    
    app.register_blueprint(user)	#注册蓝图
    
    if __name__ == '__main__':
        app.run()
    

    蓝图是需要注册在app实例上的 app.register_blueprint(bp对象)

    蓝图共享app.config

    访问网页全部都登陆
    100多个蓝图

    4 . Flask 特殊装饰器

    @app.before_request		#请求进入视图函数之前
    def be1():
        print('be1')
        return None
    
    	#return ‘出错了’  #be1 af2 af1
    @app.before_request
    def be2():
        print('be2')
        #return None
    	return ‘出错了’
    

    django是一个请求一个响应

    @app.after_request
    def af1(res):
        print('af1')
        return res
    @app.after_request
    def af2(res):
        print('af2')
        return res
    

    结果:

    be1
    be2
    af2
    af1

    替代了session + 装饰器
    部分的不好用

    @user.before_request
    def look():
        print('user1')
        return '棍'
    @user.after_request
    def look(res):
        print('user2')
        return res
    
    be1
    be2
    user2
    af2
    af1
    
    

    1 .before_request 请求进入视图函数之前进行处理 return None 继续执行否则阻断

    2 .after_request 视图函数结束 响应客户端之前

    正常周期 be1 2 3 - vf - af3 - af2 -af1

    异常周期

    3 errorhandler 重定向错误信息

    3.1 有参数的装饰器errorhandle(监听错误状态码5xx 4xx int)
    3.2 必须有一个形参接收 error_message

    @app.errorhandler(404)      #监听的端口在这
    def error(error_message):
        print(error_message)
        # return '你要访问的页面不存在' #使404 页面好看点 # 蓝图也可以使用 全局的
        # return redirect('https://www.autohome.com.cn/beijing/adgasgsdg')
        return send_file('2.jpg')       #可以打个广告
    

    代码思维:

    af : (时间密度?纠错) (解决不分先后,哪个有思路?)(缺点,珍惜)

    1 改成大众型

    把页面分开了

    @app.route('/detail')
    def detail():
        if session['username']:
            session['count'] += 1
            a = session['count']    #把session['count'] 赋值给a 然后传到前端
            name = session['username']
            print(request.args.get('id'))
            return render_template('zuoye1.html', stu_dict=STUDENT_DICT, time=a,name=name)
        else:
            return redirect('/login')
    
    @app.route('/xiangqing')
    def xiangqing():
        if session['username']:
            name = session['username']
            tag = request.args.get('id')
            tag = int(tag)
            return render_template('xiangqing.html', stu_dict=STUDENT_DICT, tag=tag , name=name)
        else:
            return redirect('/login')
    

    两个html

    zuoye.html

    <table>
    <td>id</td>
    <td>name</td>
    <td>详情</td>
    
    {% for id in stu_dict %}
        <tr>
            <td>{{ id }}</td>
            <td>{{ stu_dict[id].name }}</td>
            <td><a href="/xiangqing?id={{ id }}">点击查看</a></td>
        </tr>
    {% endfor %}
    </table>
    

    xiangqing.html

    <table>
    
    <td>id</td>
    <td>name</td>
    <td>age</td>
    <td>gender</td>
    
    {% for id in stu_dict %}
    {% if tag == id %}
        <tr>
         <td>{{ id }}</td>
            <td>{{ stu_dict[id].name }}</td>
             <td>{{ stu_dict.get(id).get('age') }}</td>
             <td>{{ stu_dict.get(id).get('gender') }}</td>
          </tr>
    {% endif %}
    {% endfor %}
    </table>
    
    

    2 使用session验证登录状态 思考:如何记录登录次数

    问题1 if session['count'] is None:

    KeyError: 'count' #还没给他赋值,所以不能判断

    解决方法 : if session.get('count') is None: # get方法取值,没有也不会报错

    先设置 session['count'] =0 当login了之后,自动就是1了(每次登陆都赋值为0,自己没想起来,听的老师的提醒)

    if uname == '123' and pwd == '123':
    	session['username'] = uname
    	#if  session['count'] is None:  #区分第一次还是第二次登录
    	 if session.get('count') is None: 
    		session['count'] = 0
    	return render_template('index.html',a=session['count'])
    
    elif uname == 'a23' and pwd == 'a23':
    	if session.get('count') is None: 
    		session['count'] = 0
    	session['username'] = uname
    	return render_template('index.html',)
    
    
    登录用到session的路由函数:
    if session['username']:
    	session['count'] += 1
                
     	name = session['username']
      	return render_template('zuoye1.html', stu_dict=STUDENT_DICT,tag= tag ,time=session['count'] ,name=name)
    用户{{ name }}第{{ time }}次session登录
    

    有session存值,即使推出了程序也会记录,默认31周,而且分别记录各个用户的登录次数,很方便

    错误写法: 逻辑不对, 两个if , 有了username就返回可以登录其他的了,但是没有,所以要去重新登录,但是登录没有放行,没有return None ,只给了有了username,但是login没有,一直走login了 所以一直302重定向

    # @app.before_request
    # def be1():
    #     # if session.get('username'):
    #     #     return None
    #     if not session.get('username'):
    #           return redirect("/login")
    

    参考了老师的写法

    @app.before_request
    def be1():
      if request.path == "/login":		#给login放行
            return None
      if not session.get("username"):
            return redirect("/login")
            
            	#别的默认放行 
            	
    或者再加上
      if session.get("username"):
            return None
    
    

    错误3 两个人的session值是一样的了?

    3 装饰器
    6 原理 ? : 解决方法: (1 加options)

    4 user car 怎么写

    cars.py 里写错了 ,改一下
    user = Blueprint('car',__name__)   -->  car = Blueprint('car',__name__)
    
    

    5 floder url why
    7 after 什么意思?
    8 笔记
    9 css 样式

    错误1 app.run('0.0.0.0:9000')

    正确:

    app.run('0.0.0.0',9000)
    

    错误2 AttributeError: 'function' object has no attribute 'name'

    好像是函数def get_login():

    不能写成login 与 login的蓝图标识重名

    jinja2.exceptions.TemplateNotFound: login.html

    detail = Blueprint('detail',__name__,template_folder='templates',static_url_path='statics')
    

    AttributeError: 'function' object has no attribute 'name'

    def detail():		#重名了	
    

    错误3 ImportError: cannot import name 'STUDENT_DICT'

    from zuoye import STUDENT_DICT
    
  • 相关阅读:
    Firemonkey 控件设定字型属性及颜色
    ListView 使用 LiveBindings 显示超过 200 条记录
    Firemonkey ListView 获取项目右方「>」(Accessory) 事件
    XE7 Update 1 选 iOS 8.1 SDK 发布 iPhone 3GS 实机测试
    Firemonkey Bitmap 设定像素颜色 Pixel
    Firemonkey 移动平台 Form 显示使用 ShowModal 范例
    XE7 提交 App(iOS 8)提示「does not contain the correct beta entitlement」问题修复
    XE7 Android 中使用 MessageDlg 范例
    导出 XE6 预设 Android Style (*.style) 档案
    修正 Memo 設定為 ReadOnly 後, 無法有複製的功能
  • 原文地址:https://www.cnblogs.com/Doner/p/11169256.html
Copyright © 2011-2022 走看看