金沙国际官网_金沙国际平台登录

因为这个金沙国际官网_金沙国际平台登录网站与很多的大型澳门赌场都有合作,金沙国际官网_金沙国际平台登录尽职尽责,高效执行,保持好奇心,不断学习,追求卓越,点击进入金沙国际官网_金沙国际平台登录马上体验吧,所以现在也正式地开始了营业。

您的位置:金沙国际官网 > 编程 > 判断是不是在微信浏览器打开

判断是不是在微信浏览器打开

发布时间:2019-11-06 08:23编辑:编程浏览(66)

    一、应用、蓝图与视图函数

    1. 结构,如图:

      图片 1

    2. Flask最上层是app核心对象 ,在这个核心对象上可以插入很多蓝图,这个蓝图是不能单独存在的,必须将app作为插板插入app ,在每一个蓝图上,可以注册很多静态文件,视图函数,模板 ,一个业务模块可以做为一个蓝图,比如book,之前的book.py 放到了app/web/路径下,就是考虑到了蓝图,app属于是整个Flask应用层,web属于是蓝图

    3. 一些初始化操作应该放入到__init__文件中,比如Flask的核心应用app初始化对象,应该放入到在应用层级app包的 __init__.py 中 ,而蓝图的初始化应该放入到蓝图层的web包__init__.py中,如图:

      图片 2

    4. Flask的核心应用app初始化对象文件app/__init__.py

    # -*- coding: utf-8 -*-
    from flask import Flask
    
    def create_app():
        app = Flask(__name__)
        app.config.from_object('config')
        # 要返回回去
        return app
    
    1. 此时在主文件中
    # -*- coding: utf-8 -*-
    from app import create_app
    
    app = create_app()
    
    if __name__ == '__main__':
        app.run(debug=app.config['DEBUG'])
    
         bool flag = false;
                string agent = System.Web.HttpContext.Current.Request.UserAgent.ToLower();
                string[] keywords = { "iphone", "ipod", "ipad", "itouch" };
    
                foreach (string item in keywords)
                {
                    if (agent.Contains(item))
                    {
                        flag = true;
                        break;
                    }
                }
                if (flag)
                {
                    ViewBag.Phone = "iOS";
                }
                else {
                    ViewBag.Phone = "Android";
                }
    
     if (agent.ToLower().Contains("micromessenger")
    {
    微信浏览器
    }
    

    RAC类关系图:

    图片 3


     

    二、用蓝图注册视图函数

    1. 在蓝图中注册试图函数,在app/web/book.py中,记得导入Blueprint
    # -*- coding: utf-8 -*-
    from flask import jsonify, Blueprint
    from helper import is_isbn_key
    from ShanqiuBook import ShanqiuBook
    
    # 蓝图 blueprint,进行初始化,蓝图的名字和参数为蓝图所在的模块名一般用__name__
    web = Blueprint ('web',__name__)
    
    # 此时这里用的就是web了
    @web.route('/book/search/<q>/<page>')
    def hello(q,page):
        is_or_key = is_isbn_key(q)
        if is_or_key == 'isbn':
            result = ShanqiuBook.search_by_isbn(q)
        else:
            result = ShanqiuBook.search_by_keyword(q)
    
        return jsonify(result)
    
    1. 在蓝图中注册了试图函数,还需要把蓝图插入到app中,app/__init__.py
    # -*- coding: utf-8 -*-
    from flask import Flask
    
    def create_app():
        app = Flask(__name__)
        app.config.from_object('config')
        # 调用一下就可以
        register_blueprint(app)
        return app
    
    # 通过这个方法插入到app中
    def register_blueprint(app):
        from app.web.book import web
        # 注册这个蓝图对象
        app.register_blueprint(web)
    

     

    RAC 信号源:

    图片 4


    三、单蓝图多模块拆分视图函数

    1. 蓝图,就是为了分模块的,比如一个web系统就是属于一个web模块,一个移动端使用的api就是一个api模块,而我们这里的book,user等不同类别的py文件,要是每一个都注册一个蓝图的话就有点小题大作了,所以要进行单蓝图
    2. 在一个模块(web)的初始文件中定义蓝图对象,然后这个模块中的其他的py文件引用的就是这一个蓝图对象来注册路由函数,
    3. 在app/web/book.py文件中
    # -*- coding: utf-8 -*-
    from flask import jsonify, Blueprint
    from helper import is_isbn_key
    from ShanqiuBook import ShanqiuBook
    # 导入web模块
    from . import web
    
    @web.route('/book/search/<q>/<page>')
    def hello(q,page):
    
        # 调用方法判断用户是根据什么查的
        is_or_key = is_isbn_key(q)
        if is_or_key == 'isbn':
            result = ShanqiuBook.search_by_isbn(q)
        else:
            result = ShanqiuBook.search_by_keyword(q)
    
        return jsonify(result)
    
    1. 这里先建立一个伪代码user.py,为了多一个模块进行演示
    # -*- coding: utf-8 -*-
    # 导入web模块
    from . import web
    @web.route("/user/login")
    def login():
        return "success"
    
    1. 此时在app/web/__init__.py文件中,定义这个蓝图对象
    # -*- coding: utf-8 -*-
    
    # 蓝图 blueprint,进行初始化
    from flask import Blueprint
    web = Blueprint ('web',__name__)
    
    # 这两个导入之后就可以成功的运行对应模块中相关的代码,注意这个位置,这蓝图实例化之后
    from app.web import book
    from app.web import user
    

     需要导入的头文件:

    1 import ReactiveCocoa
    2 import Result
    3 import ReactiveSwift
    

     

    四、Request对象

    1. 在app/web/book.py文件中,定义的url请求是/book/search/<q>/<page>这种格式的,Flask会将<>里的值自动映射成视图函数方法的参数,但是这种格式用着不爽,要把用户输入的参数作为请求参数传入,这个时候就要使用这种格式了http://127.0.0.1:5000/book/search/?q=金庸&page=1
    2. 这个该怎么获取值呢,这个时候就用到Flask内置的Request了,通过request对象就可以获取HTTP请求中包含的详细信息了,具体的用法看下面的代码
    # -*- coding: utf-8 -*-
    
    # 导入这个request模块,
    from flask import jsonify, Blueprint,request
    from helper import is_isbn_key
    from ShanqiuBook import ShanqiuBook
    from . import web
    
    # http://127.0.0.1:5000/book/search/?q=金庸&page=1
    @web.route('/book/search/')
    def hello():
        # 通过Request对象拿到对应值的信息,但是这个并不是py中原始的字典,而是dict的子类immutableDict
        q = request.args['q']
        page = request.args['page']
        # ip = request.remote_addr
    
        # 通过这个方法把它转换为普通的dict
        # a = request.args.to_dict()
        # print(a)
    
        is_or_key = is_isbn_key(q)
        if is_or_key == 'isbn':
            result = ShanqiuBook.search_by_isbn(q)
        else:
            result = ShanqiuBook.search_by_keyword(q)
    
        return jsonify(result)
    
    1. Flask的request是基于代理模式实现的,想让request正常使用,必须确保是http请求触发的函数或视图函数中使用

    冷信号

     1  //1.冷信号
     2         let producer = SignalProducer<String, NoError>.init { (observer, _) in
     3             print("新的订阅,启动操作")
     4             observer.send(value: "Hello")
     5             observer.send(value: "World")
     6             observer.sendCompleted()
     7         }
     8         
     9         //创建观察者 (多个观察者观察会有副作用)
    10         let sub1 = Signal<String, NoError>.Observer(value: { (value) in
    11             print("观察者1接受信号(value)")
    12         })
    13         
    14         let sub2 = Signal<String, NoError>.Observer(value: { (value) in
    15             print("观察者2接受信号(value)")
    16         })
    17         //观察者订阅信号
    18         print("观察者1订阅信号")
    19         producer.start(sub1)
    20         print("观察者2订阅信号")
    21         producer.start(sub2)
    

    结果:

    图片 5


     

    五、WTForms参数验证

    1. 上面我们把url改了,但是如果用户输入了一些特殊的符号该怎么办?这个时候就要使用到参数验证,而WTForms框架就是一个优秀的参数验证框架,首先在对应的环境中进行安装(flask--yQglGu4) E:pyqiyueflask>pipenv install wtforms
    2. 这个参数验证写在哪里好呢,直接写在book.py中,这样是最不妥的,为了方便调用,应该写成一个类,所以写在app/forms/book.py文件中
    # -*- coding: utf-8 -*-
    
    # 导入需要使用的模块
    from wtforms import Form,StringField,IntegerField
    from wtforms.validators import Length,NumberRange
    
    class SearchForm(Form):
        # 直接调用内置对象
        # 参数校验规则:
        # 1.定义的属性名q,page要与要校验的参数同名
        # 2.根据要传入的参数类型选择不同的Field类进行实例化
        # 3.传入一个数组,作为校验规则validators
        # 4.可以设置默认值
        q = StringField(validators=[DataRequired(),Length(min=1,max=30)])
    
        page = IntegerField(validators=[NumberRange(min=1,max=10)],default=1)
    
    1. 此时在app/web/book.py文件中就可以直接调用就行了
    # -*- coding: utf-8 -*-
    from flask import jsonify, Blueprint,request
    from helper import is_isbn_key
    from ShanqiuBook import ShanqiuBook
    from . import web
    # 导入参数校验
    from app.forms.book import SearchForm
    
    # http://127.0.0.1:5000/book/search/?q=金庸&page=1
    @web.route('/book/search/')
    def hello():
    
        # 验证层
        # 实例化我们自定义的SearchForm,需要传入一个字典作为要校验的参数
        form  = SearchForm(request.args)
        # validate()方法返回True/False来标示是否校验通过
        if form.validate():
    
            # 从form中取出校验后的q与page,并且清除空格
            q = form.q.data.strip()
            page = form.page.data
    
            is_or_key = is_isbn_key(q)
            if is_or_key == 'isbn':
                result = ShanqiuBook.search_by_isbn(q)
            else:
                result = ShanqiuBook.search_by_keyword(q)
            return jsonify(result)
        else:
            return jsonify({'msg':'参数校验失败'})
    

    热信号

     1 //        热信号 (通过管道创建)
     2         let (signalA, observerA) = Signal<String, NoError>.pipe()
     3         let (signalB, observerB) = Signal<Int, NoError>.pipe()
     4         
     5         Signal.combineLatest(signalA,signalB).observeValues { (value) in
     6             print("两个热信号收到的值(value.0) + (value.1)")
     7         }
     8         //订阅信号要在send之前
     9         signalA.observeValues { (value) in
    10             print("signalA : (value)")
    11         }
    12         
    13         observerA.send(value: "sssss")
    14         //        observerA.sendCompleted()
    15         observerB.send(value: 2)
    16         //        observerB.sendCompleted()
    17         
    18         observerB.send(value: 100)
    19         //不sendCompleted和sendError 热信号一直激活
    20         //        observerB.sendCompleted()
    

    结果: 图片 6 


     

    六、拆分配置文件

    1. 之前访问数据的时候,count和start都是写死的,现在来进行重构,之前的代码
       @classmethod
        def search_by_key(cls, q, count=15, start=0):
            # count:每页显示的数量
            # start:每页的第一条数据的下标
            url = cls.search_by_key_url.format(q, count, start)
            return HTTP.get(url)
    
    1. 这样写非常的不妥

      • 在视图函数中接收到的参数是page,代码的封装性,我们应该把count和start的计算过程放到ShanqiuBook.py的 search_by_key方法中来写

      • count的值为了方便日后的管理,这个应该放入到配置文件中,之前的配置文件是config.py,在根目录下,而这个应该放入到app目录下,而关于一些比较隐私的配置信息要妥善处理,所以在app目录下建立两个文件,secure.py用来存放私密的配置信息,setting.py用于存放一些不重要的配置信息,如下

      • app/secure.py

        # -*- coding: utf-8 -*-
        
        # 存放比较机密的配置文件,在上传git的时候不应该上传此文件
        DEBUG = True
        
      • app/setting.py

        # -*- coding: utf-8 -*-
        
        # 生产环境和开发环境几乎一样的,不怎么机密的配置文件
        
        # 每页显示的数据量
        PER_PAGE = 15
        
      • start的计算是一个单独的逻辑,应该用封装成一个方法,使用的时候直接调用

        # 获取每一页的起始下标
            @staticmethod
            def calculate_start(page):
                # 获取配置信息中的每页显示的数量
                return (page -1 ) * current_app.config['PER_PAGE']
        
    2. 重构后的ShanqiuBook.py

       -*- coding: utf-8 -*-
       from httper import httper
    # 通过这种方式来导入当前的app对象,方便调用配置而文件
    
       from flask import current_app
    
       class ShanqiuBook:
    
       isbn_url = 'http://t.yushu.im/v2/book/search/isbn/{}'
       keyword_url = 'http://t.yushu.im/v2/book/search?q={}&count={}&start={}'
    
       @classmethod
       def search_by_isbn(cls,isbn):
           url = cls.isbn_url.format(isbn)
           result = httper.get(url)
           return result
    
       @classmethod
       def search_by_keyword(cls,keyword,page=1):
           # 每页显示的数据(通过这种方式从配置文件中获取到),每一页的起始下标
           url = cls.keyword_url.format(keyword,current_app.config['PER_PAGE'],cls.calculate_start(page))
           result = httper.get(url)
           return result
    
    # 获取每一页的起始下标
       @staticmethod
       def calculate_start(page):
           return (page -1 ) * current_app.config['PER_PAGE']​
    
    1. 这个时候在app/__init__.py文件中把配置文件添加到app中
    #-- coding: utf-8 --
    
    from flask import Flask
    
    def create_app():
    
        app = Flask(name)
    
        # app.config.from_object('config')
    
        # 把配置文件装载进来
    
        app.config.from_object('app.secure')
    
        app.config.from_object('app.setting')
    
        register_blueprint(app)
    
        return app
    
    def register_blueprint(app):
    
        from app.web.book import web
    
        app.register_blueprint(web)
    

    文本框监听

    1 func racsTest() {
    2         textField.reactive.continuousTextValues.observeValues { (text) in
    3             
    4             print("值为:(text ?? "")")
    5             
    6         }
    7     }
    

     

    结果:

    图片 7


     

    七、定义第一个模型类

    1. 我们现在把文件进行整理,如下:

    图片 8

    1. 首先在本地创建一个数据库,如下:

    图片 9

    1. 在app/models/book.py文件中建立模型,这里使用到sqlalchemy来实现自动化映射,在Flask框架中对这个进行了改良Flask_SQLAlchemy,这个更加人性化,安装(flask--yQglGu4) E:pyqiyueflask>pipenv install flask-sqlalchemy

    2. 建立模型,这样就建立好了模型

    # -*- coding: utf-8 -*-
    
    # 首先导入
    from sqlalchemy import Column,Integer,String
    
    # sqlalchemy,自动化映射
    # Flask_SQLAlchemy,这个是Flask封装后的api,更加人性化
    
    class Book():
        # 需要把这些属性的默认值写成sqlalchemy提供的固定的类型
        # Column()传入参数:数据类型,主键,自增
        id = Column(Integer,primary_key=True,autoincrement=True)
        # 数据类型,不为空
        title = Column(String(50),nullable=False)
        author = Column(String(30),default='未名')
        binding = Column(String(20))
        publisher = Column(String(50))
        price = Column(String(20))
        pages = Column(Integer)
        pubdate = Column(String(20))
        # 唯一:unique=True
        isbn = Column(String(15),nullable=False,unique=True)
        summary = Column(String(1000))
        image = Column(String(50))
    
        # 定义一些方法
        def sample(self):
            pass
    

    Map映射 用于将一个事件流的值操作后的结果产生一个新的事件流。

    方法一:

    textField.reactive.continuousTextValues.map { (text) -> Int in
    
                return (text?.count)!//!.characters.count
    
                }.observeValues { (count) in
    
                    print("数值为:(count)")
    
            }
    

    输入: Hello123

    结果为:

    图片 10

     

    方法二:

     1 let (signal, observer) = Signal<String, NoError>.pipe()
     2         signal.map { (string) -> Int in
     3             return string.lengthOfBytes(using: .utf8)
     4             }.observeValues { (length) in
     5                 print("长度length: (length)")
     6         }
     7         
     8         observer.send(value: "123456")
     9         
    10         observer.send(value: "some")
    

    结果为:

    图片 11


     

    八、将模型映射到数据库中

    1. 在模型类app/models/book.py中引入导入核心对象,并实例化,继承
    # -*- coding: utf-8 -*-
    from sqlalchemy import Column,Integer,String
    
    # 将模型映射到数据库中
    # 首先导入核心的对象
    from flask_sqlalchemy import SQLAlchemy
    
    # 初始化
    db = SQLAlchemy()
    
    # 继承db.Model
    class Book(db.Model):
        id = Column(Integer,primary_key=True,autoincrement=True)
        title = Column(String(50),nullable=False)
        author = Column(String(30),default='未名')
        binding = Column(String(20))
        publisher = Column(String(50))
        price = Column(String(20))
        pages = Column(Integer)
        pubdate = Column(String(20))
        isbn = Column(String(15),nullable=False,unique=True)
        summary = Column(String(1000))
        image = Column(String(50))
    
    1. app/__init__.py中进行模型与flask关联
    # -*- coding: utf-8 -*-
    from flask import Flask
    # 导入这个db
    from app.models.book import db
    
    def create_app():
        app = Flask(__name__)
        app.config.from_object('app.secure')
        app.config.from_object('app.setting')
        register_blueprint(app)
    
    
        # 把这个db和核心对象关联起来了
        db.init_app(app)
        # 注意这里,这样写的话会报错
        db.create_all() # 把所有的数据模型映射到数据库中
        return app
    
    def register_blueprint(app):
        from app.web.book import web
        app.register_blueprint(web)
    
    1. 配置数据库连接的配置文件在app/secure.py文件中
    # -*- coding: utf-8 -*-
    
    # 存放比较机密的配置文件
    DEBUG = True
    
    # 数据库连接url,固定格式
    # 要连接的数据库类型,数据库驱动(这里还要进行安装:pipenv install cymysql)
    SQLALCHEMY_DATABASE_URI = 'mysql+cymysql://root:123456@localhost:3306/book'
    
    1. 之后运行项目,就会创建在指定的数据库中创建一个数据表了,但是运行项目会出现下面的这种错误
        'No application found. Either work inside a view function or push'
    
    这个是因为在Flask中,不是实例化了app核心对象,其他代码就可以直接使用,要在上面的第二步的注意事项中` db.create_all()`方法中,把app核心对象传入即可
    

    db.create_all(app=app),这样就可以了,在数据库中就可以看到表了

    图片 12

    Filter函数可以按照之前预设的条件过滤掉不满足的值

    方法一:

    1 textField.reactive.continuousTextValues.filter { (text) -> Bool in
    2             
    3             return text!.characters.count > 3
    4             
    5             }.observeValues { (text) in
    6                 
    7                 print(text ?? "")
    8                 
    9         }
    

    输入: 1234

    结果:

    1234 

     

    方法二:

     1 let (signal, observer) = Signal<Int, NoError>.pipe()
     2         signal.filter { (value) -> Bool in
     3             return value % 2 == 0
     4             }.observeValues { (value) in
     5                 print("(value)能被2整除")
     6         }
     7         observer.send(value: 3)
     8         observer.send(value: 4)
     9         observer.send(value: 6)
    10         observer.send(value: 7)
    

     

    结果:

    4能被2整除

    6能被2整除


     

    信号合并

    合成后的新事件流只有在收到每个合成流的至少一个值后才会发送出去。接着就会把每个流的最新的值一起输出。

     1 //        信号合并 两个要被订阅combineLatest 才能被订阅,被订阅后,合并中其中一个sendNext都会激活订阅
     2         let (signalA, observerA) = Signal<String, NoError>.pipe()
     3         let (signalB, observerB) = Signal<Array<Any> , NoError>.pipe()
     4         Signal.combineLatest(signalA, signalB).observeValues { (value) in
     5             print("合并的信号:(value)")
     6         }
     7         
     8         observerA.send(value: "xxx")
     9         observerA.sendCompleted()
    10         observerB.send(value: ["sdsd","ddddd"])
    11         observerB.sendCompleted()
    

    结果:

    图片 13


     

    本文由金沙国际官网发布于编程,转载请注明出处:判断是不是在微信浏览器打开

    关键词: