zoukankan      html  css  js  c++  java
  • Flask入门到项目实战

       认识web
            URL详解
               url是 uniform Resource Locator 的简写,统一资源定位符
            一个URL由以下几个部分组成:
                
    scheme://host:port/path/?query-string=xx#anchor
    

      

            scheme:代表的是访问的协议,一般为http或者https以及ftp等
            host:主机名,域名,比如www.google.cn
            port:端口号。当你访问一个网站的时候,浏览器默认的使用80端口
            path:查找路径。比如www.jianshu.com/trending/now,后面的trending/now就是path
            query-string:查找字符串,比如www.baidu.com/s?wd=python,后面的wd=python就是查询字符串
            anchor:锚点,后台一般不用管,前端用来做页面的定位的
    注意:URL中的所有字符都是ASSCII字符集,如果出现非ASCII字符,比如中文,浏览器会进行编码再传输
    笔记:如果使用的是http协议,那么浏览器就会使用80端口去请求这个服务器的资源
               如果使用的是https协议,那么浏览器就会使用443端口去请求这个服务器的资源
     
    Web服务器和应用服务器以及web应用框架
        Web服务器:负责处理http/https请求,响应静态文件,常见的有Apache,Nginx以及微软IIS
        应用服务器:负责处理逻辑的服务器。比如php,python的代码,是不能直接通过nginx这种web服务器来处理的密支那通过应用服务器来处理,常见的应用服务器有uwsgi,tomcat
    Web应用框架:一般使用的某种语言,封装了常用的web功能的框架就是web应用框架,flask,Django以及Java中的SSH(Structs2+Spring3+Hibernate3)框架都是web应用框架
     
    第一个flask程序讲解
        1.第一次创建项目的时候,要添加flask虚拟环境,添加虚拟环境的时候,一定要选择到python这个执行文件。比如你的flask的虚拟环境的目录在/User/Virtualenv/flask-env/bin/python
        2.flask程序代码详细解释
        #encdding:utf-8
     
        # 从flask这个框架中导入Flask这个类
        from flask import Flask
        # 初始化一个Flask对象
        # Flask()
        # 需要传递一个参数__name__
        # 1.方便flask框架去寻找资源
        # 2.方便flask插件比如Flask-Sqlalchemy出现错误的时候美好去寻找问题所在的位置
     app = Flask(__name__)

        # @app.route是一个装饰器

      # @开头,并且在函数的上面,说明是装饰器

        # 这个装饰器的作用,是做一个url与视图函数的映射
        # 127.0.0.1:5000/ -> 去请求hello_world这个函数,然后将结果返回给浏览器
     @app.route('/')
        def hello_world():
            return 'Hello World!'

     # 如果当前这个文件是作为入口程序运行,那么就执行app.run()

        if __name__ == '__main__':
            # app.run()
            # 启动一个应用服务器,来接受用户的请求
            # while True():
            #     listen()
            app.run()

    设置debug模式

        1.在app.run()中传入一个关键字参数debug,app_run(debug=True),就设置当前项目为debug模式
        2.debug模式的两大功能:
            *当程序出现问题的时候,可以在页面中看到错误信息和出错的位置
            *只要修改了项目中的python文件,程序会自动加载,不需要手动重新启动程序
     
    使用配置文件
        1.新建一个`config.py`文件
        2.在主app文件中导入这个文件,并且配置到`app` 中,示例代码如下:
          
    ```import config
        app.config.form_object(config)
        3.还有许多其他的参数,都是在这个配置文件中,比如`SECRET_KEY`,`SQLALCHEMY`这些配置,都是在这个文件中
    Url传参数
        1.参数的作用:可以在相同的url,但可以指定不同的参数,来加载不同的数据
        2.在flask中如何使用参数:
            
        @app.route(‘/aritcle/<id>’)
        def aritcle(id):
            return u’您请求的参数是: %s’ % id 
        *参数需要放在两个尖括号中
        *视图函数中需要放与url同名的参数s
    反转URL
        1.什么叫做反转url:从视图函数到url的转换叫做反转url
        2.反转url的用处:
            *在页面重定向的时候,会使用url反转
            *在模板中,也会使用url反转
    页面跳转和重定向
        1.用处:在用户访问一些需要登录的页面的时候,如果用户没有登录,那么可以让他重定向到登录页面
        2.代码实现:
        from flask import redirect, url_for
        Redirect(url_for(‘login')
     
    Flask渲染模板Jinja2模板和传参
        1.如何渲染模板
            *模板放在`templates`文件夹下
            *从`flask`中导入`render_template`函数
            *在视图函数中,使用`render_template`函数,渲染模板,注意:只需要填写模板的名字,不需要填写`templates`这个文件夹的路径
        2.模板传参
            *如果只有一个或者少量参数,直接在`render_template`函数中添加关键字参数就可以了。
            *如果有多个参数的时候,那么可以先把所有的参数放在字典中,然后再`render_template`中使用2个*,把字典转换成关键字传递进去,
             这样的代码更加方便管理和使用
        3.在模板中如果要使用一个变量,语法是:`{{ params }}`
        4.访问模型中的属性或者是字典,可以通过`{{ params.property}}`或者是使用{{ params[‘property']}}都是可以的
    If判断
        1.语法
           {% if XXX %}
           {% else %}
           {% endif %} 
     
    过滤器(有很多去官网)
        1.介绍和语法
            *介绍:过滤器可以处理变量,把原始的变量经过处理后再展示出来。作用的对象是变量
            *语法:
            {{ avater|default(‘xxx’)}}
        2.default过滤器:如果当前变量不存在,这个时候可以指定默认值
        3.length过滤器:求列表或者字符串或者字典或者元组的长度  
           {{ list|length }}
        4.常用的过滤器(自己百度)
          
    继承和block(用于前端页面)
        1.继承作用和语法
            *作用:可以把一些公共的代码放在父模板中,避免每个模板写同样的代码
            *语法 
            {% extends ‘base.html' %}
        2.block实现
            *作用:可以让子模板实现一些自己的需求,父模板需要提前定义好
            *注意点:子模板中的代码,必须放在block块中
     
    URL链接:
        使用`url_for(视图函数名称)`可以反转url
     
    加载静态文件
        1.语法`url_for(’static’, filename=‘路径’)`
        2.静态文件,flask会从`static`文件夹中开始寻找,所以不需要再写`static`这个路径
        3.可以加载`css`,`js`,`Image`....所有的静态文件 
        <link rel=“stylesheet” href=“{{ url_for(’static’, filename=‘css/index.css’) }}”
        <script src=“{{ url_for(’static’, filename=‘js/index.js’) }}”
        <img src=“{{ url_for(’static’, filename=‘images/index.png')}}"
    Flask-SQLAlchemy的介绍
        1.ORM: Object Relationship Mapping (模型关系映射)
        2.flask-sqlalchemy是一套ORM框架
        3.ORM的好处:可以让我们操作数据库跟操作对象是一样的,非常方便,因为一个表就抽象成一个类,一条数据就抽象成该类的一个对象。 
     
    建库 create database db_demo1 charset utf8;
     
    Flask-SQLAlchemy的使用
        1.初始化和设置数据库配置信息
            *使用flask_sqlalchemy中的SQLAlchemy进行初始化 
            From flask_sqlalchemy import SQLAlchemy
            app = Flask(__name__)
            db = SQLAlchemy(app)
        2.设置配置信息:在’config.py’文件中添加以下配置信息 
     #mysql+mysqldb://username:password@host:port/database
        DIALECT = 'mysql'
        DRIVER = 'mysqldb'
        USERNAME = 'root'
        PASSWORD = '123'
        HOST = '127.0.0.1'
        PORT = '3306'
        DATABASE = 'db_demo1'
        SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8  ".format(DIALECT, DRIVER, USERNAME, PASSWORD, HOST, PORT, DATABASE)
        SQLALCHEMY_TRACK_MODIFICATIONS = False

     3.在主app文件中,添加配置文件: 

     From flask_sqlalchemy import SQLAlchemy
            app = Flask(__name__)
            db = SQLAlchemy(app)

       4.做测试 

        db.create_all()
            如果没有报错,说明配置没有问题。
    SQLAlchemy的增删改查
        1.增      
    article1 = Article('111',2222)
            db.session.add(article1)
            db.session.commit()

     2.删 

    #
    # 先查后删再提交
    article2 = Article.query.filter(Article.title == 'aaa').first()
    db.session.delete(article2)
    db.session.commit()

       3.改    

       
     #
     # 先查后改再提交
     article2 = Article.query.filter(Article.title == '111').first()
     article2.title = 'aaa'
     db.session.commit()
      

       4.查   

     #
      article2 = Article.query.filter(Article.title == 'aaa').first()
      if article2:
          print article2.title,article2.content
    【**重点**】
    Flask-SQLAlchemy外键及其关系
        1.外键       
    #用户表
    class User(db.Model):
        __tablename__ = 'user'
     
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        username = db.Column(db.String(100), nullable=False)
     
        def __init__(self, username):
            self.username = username

    #文章表

    class Article(db.Model):
        __tablename__ = 'aritcle'
     
        id = db.Column(db.Integer, primary_key=True,autoincrement=True)
        title = db.Column(db.String(100), nullable=False)
        content = db.Column(db.Text, nullable=False)
        author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
        # 正向引用反向引用
        author = db.relationship('User', backref=db.backref('articles'))
     
        def __init__(self, title, content, author_id):
            self.title = title
            self.content = content
            self.author_id = author_id
    
    db.create_all()
    author = db.relationship('User', backref=db.backref('articles’))
    解释:
        *给`Article`这个模型添加一个`author`属性,可以访问这篇文章的作者数据,像访问普通属性一样。
        *`backref`是定义反向引用,可以通过`User.article`访问这个模型所写的所有文章
     
        2.多对多
            *多对多的关系,要通过一个中间表进行关联
            *中间表,不能 ` class ` 的方式实现,只能通过 ` db.Table ` 的方式实现。
            *设置关联:` tags = db.relationship(’Tag’, secondary=article_tag, backref=db.backref(‘articles’)) ` 需要使用一个关键字 ` secondary=中间表名 `来进行关联
            *访问和数据添加可以通过以下方式进行操作: 
        1.添加:
      article1 = Article(title='bbb')
      article2 = Article(title='ccc')
     
      tag1 = Tag(name='111')
      tag2 = Tag(name='222')
     
       article1.tags.append(tag1)
       article1.tags.append(tag2)
     
       article2.tags.append(tag1)
       article2.tags.append(tag2)
     
       db.session.add(article1)
       db.session.add(article2)
     
       db.session.add(tag1)
       db.session.add(tag2)
     
       db.session.commit()
        2.访问
            
    article1 = Article.query.filter(Article.title == 'bbb').first()
    tags = article1.tags
    for tag in tags:
        print tag.name
    Flask-Scripte的介绍与安装与使用
        1.Flask-Script:Flask-Script的作用是可以通过命令行的形式来操作Flask,例如通过命令跑一个开发版本的服务器,设置数据库,定时任务等。
        2.安装:pip install flask-script 
        3.如果直接在主 ` manage.py ` 中写命令,那么在终端就只需要 ` python manage.py  command_name ` 就可以了
        4.如果把一些命令集中在一个文件中,那么在终端就需要输入一个父命令,比如 ` python manage.py db init`
        5.案例代码 
    #encoding: utf-8
     
    from flask_script import Manager
     
    DBManager= Manager()
     
    @DBManager.command
    def init():
        print "数据库初始化"
     
    @DBManager.command
    def migrate():
        print "数据库迁移"
     
    #encoding: utf-8
     
    from flask_script import Manager
    from flask_script_demo import app
    from db_scripts import DBManager
     
    mananger = Manager(app)
     
    mananger.add_command('db', DBManager)
     
    @mananger.command
    def runserver():
        print '服务器运行成功!'
     
    if __name__ == '__main__':
        mananger.run()
    分开 ` models `以及解决循环引用:
        1.分开 ` models `的目的是为了让代码更加方便管理
        2.如何解决循环引用:把 ` db `放在一个单独的文件中,切断循环引用就可以了。 
     
    Flask-Migrate的介绍和使用
        1.介绍:因为 ` db.create_all ` 在后期修改字段的时候,不会自动映射到数据库,必须删除表,然后重新运行 ` db.create_all ` 才会重新映射,这样不符合实际需求,因此flask-migrate就是为了解决这个问题,它可以在每次修改的东西映射到数据库中。
        2.安装 ` pip install flask-migrate ` 
        3.使用 ` flask_migrate `必须借助 ` flask-scripts `,这个包的 ` MigrateCommand  ` 中包含了所有和数据库相关的命令
        4. ` flask_migrate ` 相关命令
            * ` python manage.py db init `: 初始化一个迁移脚本环境,只需要执行一次
            * ` python manage.py db migrate `: 将模型生成迁移文件,只要模型更改了,就需要执行一遍这个命令
            * ` python manage.py db upgrade `: 将迁移文件真正映射到数据库中,每次运行了 ` migrade `命令后,就要记得运行这个命令
     
    cookie:
        1. ` cookie ` 出现的原因:在网站中,http请求是无状态的,也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求的是哪个用户,cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存到本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪一个。
        2.如果服务器返回了 ` cookie `给浏览器,那么浏览器下次再请求相同的服务器的时候,就会自动的把 ` cookie ` 发送给浏览器,这个过程,用户根本不需要管。
     
    session:
    1. ` session ` 介绍:session和cookie的作用有点类似,都是为了存储用户相关信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但服务器已经发展至今,保存一些session信息还是绰绰有余的
    2. 使用 ` session `的好处:**1.敏感数据不是直接发送给浏览器,而是发送一个` session_id `,服务器将 ` session_id `和敏感数据做一个映射存储在 ` session `(在服务器上面)中,更加安全。**2.` session ` 可以设置过期时间,也从另一个方面,保证了用户的账号安全
     
    flask中的session工作机制
         1.介绍:把敏感数据加密后放入` session `中,然后把 ` session `存放到 ` cookie `中,下次请求的时候,再从浏览器发送过来的 ` cookie `中读取 ` session `然后再从` session `中读取敏感数据,并进行解密,获取最终用户数据。
        2.flask的这种 ` session `机制,可以节省服务器的开销,因为把所有的信息都存储到了客户端(浏览器)
        3.安全是相对的,把 ` session `放到 ` cookie `中,经过加密,也是比较安全的,这点大家可以放心使用。  
     
    flask中使用cookie和session
        1.cookies:在Flask中操作cookie,是通过response对象来操作,可以在response返回之前,通过response.set_cookie来设置,这个方法有以下几个参数需要注意:
            *key:设置cookie的key
            *value:key对应的value
            *max_age:改cookie的过期时间,如果不设置,则浏览器关闭后就会自动过期
            *expires:过期时间,应该是一个datetime类型
            *domain:改cookie在哪个域名中有效,一般设置子域名,比如cms.example.com
            *path:该cookie在哪个路径下有效
     
        2.session:Flask中的session是通过from flask import session 。然后添加值key和value进去即可,并且,Flask中的session机制是将session信息加密,然后存储在cookie中,专业术语叫做 client side session
     
    操作session
        1.session的操作方式:
            *使用 ` session `需要从` flask `中导入 ` session `,所有和 ` session `相关的操作都是通过这个变量
            *使用 ` session `需要设置 ` SECRET_KEY `,用来作为加密的秘钥。并且这个 ` SECRET_KEY `如果每次服务器启动后都会变化的话,那么之前的 ` session ` 就不能再通过当前这个` SECRET_KEY `进行解密了
            *操作 ` session `的时候,跟操作字典是一样的。
            *添加 ` session `:` session[‘username'] `。
            *删除 ` session.pop(‘username’) ` 或者 ` del session[‘username’] `
            *清除所有 ` session `:`session.clear() `
            *获取 ` session.get(‘XXX’) `
        2.设置session的过期时间
            *如果没有指定session的过期时间,那么默认是浏览器关闭后就自动结束
            *如果设置了session的permanent属性为True,那么过期时间是31天
            *可以通过给 ` app.config ` 设置 ` PERMANENT_SESSION_LIFETIME `来更改过期时间,这个值得数据类型是` datetime.timedelay` 类型
     
    Get请求和post请求
        1.get请求
            *使用场景:如果只对服务器获取数据,并没有对服务器产生任何影响,那么这个时候使用get请求。
            *传参:get请求参数是放在url中,并且是通过 ` ? `的形式来指定key和value。
        2.post请求
            *使用场景:如果要对服务器产生影响,那么使用post请求
            *传参:post请求传参不是放在url中,是通过 ` form data `的形式发送给服务器
    get和post请求获取参数
        1.get请求是通过 ` request.args `来获取
        2.post请求是通过 ` request.form `来获取
        3.post请求在模板中要注意几点:
            *input标签中,要写name来标识这个value和key,方便后台获取
            *在写form表单的时候,要指定 ` method=‘POST’ `,并且要指定 ` action=‘/login/ ` 
     4.示例代码
       
     <form action="{{ url_for('login') }}" method="post">
            <table>
                <tbody>
                    <tr>
                        <td>用户名:</td>
                        <td><input type="text" name='username' placeholder="请输入用户名"></td>
                    </tr>
                    <tr>
                        <td>密码:</td>
                        <td><input type="text" name='password' placeholder="请输入密码"></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td><input type="submit" placeholder="登录"></td>
                    </tr>
                </tbody>
            </table>
        </form>
    保存全局变量的g属性
            g: global
              1.g对象是专门用来保存用户的数据的
              2.g对象在一次请求中,都是可以使用的  
     
    钩子函数(hook):
        1.before_request:
            *在请求之前执行
            *是在视图函数执行之前执行
            *这个函数这是一个装饰器,它可以把需要设置为钩子函数的代码放到视图函数执行之前来执行
        2.context_processor:
            *上下文处理器应该返回一个字典,字典中的 ` key ` 会被模板中当成变量来渲染
            *上下文处理器返回字典,在所有页面中都是可用的
            *被这个装饰器修饰的钩子函数必须要返回一个字典
     
  • 相关阅读:
    socket的双重属性
    Client/Server 模型 与socket
    简单理解Socket 重要
    C++ 异常处理机制的实现
    ARM汇编之MOV指令
    指令集 与 cpu
    寄存器简介 与 ebp esp
    ESP和EBP 栈顶指针和栈底指针
    函数调用过程栈帧变化详解
    栈帧
  • 原文地址:https://www.cnblogs.com/xushuhai/p/8847104.html
Copyright © 2011-2022 走看看