• 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
    
  • 相关阅读:
    Devrama Slider
    全栈开发必备的10款 Sublime Text 插件
    经典网页设计:使用颜色滤镜效果的20个网站
    Nibbler – 免费的网站测试和指标评分工具
    使用 HTML5 Canvas 绘制出惊艳的水滴效果
    Qt4 和 Qt5 模块的分类
    设计Qt风格的C++API
    Qt属性系统
    Qt实现艺术字效果
    Qt中容器类应该如何存储对象(最好使用对象指针类型,如:QList<TestObj*>,而不要使用 QList<TestObj> 这样的定义,建议采用 智能指针QSharedPointer)
  • 原文地址:https://www.cnblogs.com/Doner/p/11169256.html
Copyright © 2020-2023  润新知