flask基础

1.flask和django的区别

复制代码
    django是个大而全的框架,flask是一个轻量级的框架,flask的扩展性比较好,有很多第三方组件
    django的内部为我们提供了非常多的组件:
        orm
        serrion$cookie
        admin
        form
        modelform
        路由
        视图
        模板
        中间件
        分页
        auth
        content-type
        缓存
        信号
        多数据库连接(django的数据库配置文件中可以体现)
        
    flask框架本身没有太多的功能:路由/视图/模板(jinja2)/session/中间件 ,第三方组件非常齐全。 
    
    重要具体区别    
       0.django的请求处理是逐一封装和传递; flask的请求是利用上下文管理来实现的。
      1.请求的存放地址不同    
         flask的请求时利用上下文管理来实现的(是将请求放到一个地方)
         django的请求处理是逐一封装和传递
      2.session的处理不同
        django是存放在数据库中
        flask是存放在加密的cookie里面,存放到用户浏览器里面
    还有一些更小的区别
        3.flask的配置可以放在flask对象里面,可以在里面传入配置文件,和模板的配置等
        4.dlask有一些特殊的装饰器:
            before_first_request
            before_request
            after_request
            route
            tempalte_global
            template_filter
复制代码

 2.flask的快速使用

复制代码
知识点一:
 __call__和__init__和__new__
    __call__:有__call__方法的实例对象将成为可调用的对象,就可以在后面加括号执行
    __init__:对实例进行初始化,里面是self
    __new__:创建一个实例对象,里面的是cls
知识点二:
  安装flask会有好多依赖,其中比较重要的是:
  pip install flask
    Markupsafe:安全的熏染模板
    jinjia2:模板,flask不提供,flask作者基于django的模板开发的
    werkzeug:
      wsgi(web服务网关接口文本:web server getway interface ,是一种协议),是python语言定义的web服务器和web应用程序之间的一种简单而通用的及接口
      注意:flask没有wsgi服务器,必须使用第三方的。flask使用的是werkzeug。本质是socket
复制代码

3.flask依赖于wsgi werkzeug

复制代码
注意:
    werkzeug可已单独作为服务器使用,但是没有路由匹配,只有socket链接
eg1:
    from werkzeug.serving import run_simple
    def func(environ,start_response):
        print('来了')
        return None

    if __name__ == '__main__':
    run_simple('127.0.0.1',5555,func)

eg2:
    from werkzeug.serving import run_simple
    class Task():
        def __call__(self,environ,start_response):
            return "对象"
    
    app = Task()

    if __name__ == '__main__':
        run_simple('127.0.0.1',5555,app)
    # 其中一个类的对象加括号()的时候,会先执行__call__方法。
    # 关于 call 方法,不得不先提到一个概念,就是可调用对象(callable),我们平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把一对括号()应用到某个对象身上都可称之为可调用对象,判断对象是否为可调用对象可以用函数 callable。
    # 如果在类中实现了 __ call __ 方法,那么实例对象也将成为一个可调用对象,就可以在实例对象后面添加扩号
    # 或者记住:对象加(),就是执行__call__方法
   # 其中run_simple的执行的时第三个参数加()
eg3: from werkzeug.serving import run_simple class Task(): def __call__(self,environ,start_response): return "对象" # 其中__call__执行的是flask的东西 def run(self): run_simple('127.0.0.1',5555,self) # 其中的self指的是app = Task() app = Task() if __name__ == '__main__': app.run() # 相当于执行run_simple,调用了werkzeug。其中run_simple调用了__call__方法,因为self=app=Task 总结: 1.flask的框架是基于werkzeug的wsgi实现的,flask和django本身自己没有wsgi 2.flask的请求一旦进来,先执行的是app的__call__方法。,其中__call__方法执行的是flask自己的东西 3.写flask的时候,会有一个标准的流程
复制代码

 4.基于flask的hello world

复制代码
    from flask import Flask
    # 创建flask对象
    app = Flask(__name__)

    # 创建url和视图的对应关系
    @app.route('/index')
    def index():
        return "hello world~"

    # app的run调用run_simple,run_simple调用wsgi服务器werkzeug,让flask程序启动起来
    if __name__ == '__main__':
        app.run()
复制代码

 5.基于flask的用户登录,增删改查

复制代码
源码
  from flask import Flask,render_template,jsonify,request,redirect,url_for
    app = Flask(__name__)
    data_dict = {
        '1':{"name":"admin","age":73},
        '2':{"name":"kobe","age":84}
    }
    @app.route('/login',methods=['GET','POST'])
    def login():
        if request.method =="GET":
            return render_template('login.html')
        else:
            user = request.form.get('user')
            pwd = request.form.get('pwd')
            if user == 'admin' and pwd == '123':
                return redirect('/index')
            error = "用户名密码失败~"
            # return render_template('login.html',**{"error":error})
            return render_template('login.html',error=error)

    @app.route('/index',endpoint='idx')
    def index():
        return render_template("index.html",data=data_dict)

    @app.route('/edit',methods=['GET','POST'])
    def edit():
        nid = request.args.get('nid')
        if request.method == 'GET':
            dict  = data_dict[nid]
            return render_template('edit.html',dict=dict)
        user = request.form.get('user')
        age = request.form.get('age')
        data_dict[nid]['name'] = user
        data_dict[nid]['age'] = age
        return redirect(url_for('idx'))


    @app.route('/del/<nid>')  # 这么写的意思是在del函数后面可以接受一个值,并且可以转成int类型
    def delete(nid):
        # nid = request.args.get('nid')
        del data_dict[nid]
        return redirect(url_for('idx'))

    if __name__ == '__main__':
        app.run()

总结
    路由:
        @app.route('/index',methods=["GET","POST"],endpoint='idx')
        def index():
            pass
        1.flask的路由带了装饰器
        2.路由的参数支持三个,其中endpoint默认值等于函数的名字
        3.同一个flask程序里面不能重名(重点)
        4.支持动态路由
            @app.route('/index/<int:nid>')
            def test(nid):
                pass
        5.@app.route('/login',methods=['GET','POST'])
            默认只支持get请求。如不添加,则会爆方法不允许的错误
                
    设置templates
        app = Flask(__name__,template_folder="")
        template_folder 设置模板的文件夹,默认等于templates
        
    参数的获取:
        request flask的请求数据都在request里面,必须先导入from flask import request,Flask
            request.data
            request.from.get("user") 回去请求体中的数据
            request.args.get() 获取url上面的参数,通过get方式传递参数,django里面是request.get('nid')
    返回数据:
        return "返回字符串"
        jsonify 返回json格式的数据
        render_template 返回模板,render_template内部调用了**context来打散
            error = "用户名密码失败~"
            return render_template('login.html',**{"error":error})
            return render_template('login.html',error=error)
    
    跳转页面:
        redirect 跳转页面
            1.可以写函数名 return redirect('/index')
            2.可以写别名 return redirect(url_for('idx'))
                注意这是url上面的别名,是endpoint='idx'
                @app.route('/index', endpoint='idx')
                def index():
                    return render_template("index.html", data=data_dict)                
    传递的参数:
        url传值
            前端:
                < a href = "/edit?nid={{key}}" > 编辑 < / a >  # 以url的方式传值,通过get方式
            后端:
                @app.route('/edit')
                def edit():
                    nid = request.args.get('nid')
                    print(nid)
                    return "编辑"
        url传值
            前端:
                <a href="/del/{{key}}">删除</a>
            后端:
                @app.route('/del/<int:nid>')  # 这么写的意思是在del函数后面可以接受一个值,并且可以转成int类型@app.route('/del/<int:nid>')
                def delete(nid):  # 这里面的nid是接收前端传递过来的参数
                    # nid = request.args.get('nid')
                    print(nid)
                    return "删除"
    模板处理数据:
        1. {{ info }}
        2. {% for item in info %}
                {{item}}
            {% endfor %}
        3.模板循环字典
            {% for key,value in data.items() %}  #在flask里面的字典等必须加()
            <tr>
                <td>{{key}}</td>
                <td>{{value.name}}</td>
                <td>{{value['age']}}</td>  # 按照字典的方式处理
                <td>{{value.get('age',11111)}}</td>  # 按照字典的方式处理,还可以设置默认值
                <td>
                    <a href="">编辑</a>
                    <a href="">删除</a>
                </td>
            </tr>
            {% endfor%}
            
    jinjia2模板注释:
        不能使用html的注释,而是要在前端使用 {# <h1>hello</h1> #}
复制代码

6.给flask视图添加装饰器

复制代码
  1.装饰器执行顺序
        @cdx
        @abx
        def login():
            pass
        # 装饰器的执行顺序是从靠近函数的第一个装饰器向上执行
        # 返回值顺序,正好相反    
    
    2.flask框架下,页面从上向下加载,当读取到@app.route('/index')的时候,会读取其下面的函数
        生成一个对应关系。就是url和视图函数的对应关系。
        
        import functools
        app = Flask(__name__)

        def auth(func):
            # @functools.wraps(func)
            def inner(*args,**kwargs):
                return func(*args,**kwargs)
            return inner

        @app.route('/login',endpoint='abc')
        @auth
        def login():
            pass

        @app.route('/index',endpoint='ind')
        @auth
        def index():
            pass
        
        这样运行就会报错,。。。。。。。endpoint functions:inner
        提示我们有两个相同的inner
        因为:
            两个函数都被装饰器@auth装饰,实际上都是执行的inner函数。但是flask框架endpoint默认在不写的情况下等于函数名。
            所以会报错两个函数都等于inner,所以爆错
        解决办法:
            1.给每个函数设置endponit值,
            2.使用import functools,在inner函数上@functools.wraps(func)。
复制代码

7.flask路由

复制代码
路由:
    作用:将从客户端发送过来的请求分发到指定的函数上

    # 实际上app.route()是把rule(路由)提交到ad_ulr_rule函数中。
    @app.route('/index1')
    def index1():
        return '<font>Hello World!</font>'

    def index2():
        return 'welcome add_url_rule'

    app.add_url_rule('/index2','index2',view_func=index2)
    # 这个装饰器其实就是将rule字符串跟视图函数进行绑定,通过add_url_rule()函数绑定   # @app.route('/index2')底层是调用的add_url_rule()


路由传参(路由的变量规则):
    写法:
        <converter:variable_name>

    converter类型:
        string:接收任何没有斜杠/的文件(默认)
        path:接收路径,可接收斜线/, 从path开始后面的都是参数,斜线/没有作用
        int:接收整形
        float:接收浮点型
        uuid:只接受uuid字符串,唯一码,一种生成规则
        any:可以同时指定多种路径,进行限定

    路由传参的参数获取:
        @blue.route('/')
        def index():
            return 'index page~~'

        @blue.route('/users/<int:id>/')
        def users(id):
            print (id)
            print (type(id))
            return 'users api'

        @blue.route('/getpath/<path:address>')
        def getpath(address):
            print (address)
            print (type(address))
            return 'getpath api'

        @blue.route('/getany/<any(a,b):an>')
        def getany(an):
            print (an)
            print (type(an))
            return 'getany api'

    传递的参数:
        url传值
            前端:
                < a href = "/edit?nid={{key}}" > 编辑 < / a >  # 以url的方式传值,通过get方式
            后端:
                @app.route('/edit')
                def edit():
                    nid = request.args.get('nid')
                    print(nid)
                    return "编辑"
        url传值
            前端:
                <a href="/del/{{key}}">删除</a>
            后端:
                @app.route('/del/<int:nid>')  # 这么写的意思是在del函数后面可以接受一个值,并且可以转成int类型@app.route('/del/<int:nid>')
                def delete(nid):  # 这里面的nid是接收前端传递过来的参数
                    # nid = request.args.get('nid')
                    print(nid)
                    return "删除"

路由跳转
    第一点:
        路由中定义'/index/',无论请求的url是否带有后面的/,都可以执行视图函数
        如果请求的是/index,也会执行,只不过是308重定向到/index/过去了

    第二点:
        多有的路由搜索规则都是自伤而下搜索的,在写路由的时候,定义的路由需要唯一。
复制代码

8.视图函数,route规则

复制代码
请求方法
    @app.route('/',methods=['GET','POST'])
    def hello():
        return "lol"

methods中指定请求方法,默认支持GET,HEAD,OPTIONS,其他请求需要手动注册
    GET
    POST
    HEAD
    PUT
    DELETE

url_for
    反向解析,根据函数endpoint名字,获取反向路径
    url_for('endpoint',参数名=value)
        # 使用url_for()反解析: 即使当路由发生改变时,依然能通过视图函数访问对应的路由
        1.没有蓝图管理路由: {{ url_for(' endpoint ', 参数) }}
        2.用蓝图管理路由时: {{ url_for(' 蓝图名字.endpoint ', 参数) }}
    注意:
     默认情况下,endpoint等与函数名称 前端显示:
<h2> <a href="{{ url_for('index1func',id=1) }}">home页面--->index1页面</a></h2> ​ 后端接收: # 通过定义转换器 /< >/ 接收,再传参到视图函数 # 该链接 请求相当于: 路由地址 /index1/1/ @app.route('/index1/<int:id>/') def index1func(id): print(id) # 1 return render_template('index1.html') redirect 从定向 1.可以写函数名 return redirect('/index') 2.可以写别名 return redirect(url_for('idx')) # 注意这是url上面的别名,是endpoint='idx' @app.route('/index', endpoint='idx') def index(): return render_template("index.html", data=data_dict) 总结: @app.route('/index',methods=["GET","POST"],endpoint='idx') def index(): pass 1.flask的路由带了装饰器 2.路由的参数支持三个,其中endpoint默认值等于函数的名字 3.同一个flask程序里面不能重名(重点) 4.支持动态路由 @app.route('/index/<int:nid>') def test(nid): pass 5.@app.route('/login',methods=['GET','POST']) 默认只支持get请求。如不添加,则会爆方法不允许的错误
复制代码

9.flask中request对象

复制代码
服务器在接收到客户端的请求后,会自动创建Request对象,有flask框架创建,Request对象不可修改
from flask import request
属性:
    url # 完整的请求地址
    base_url # 去掉get参数的url
    host_url # 只有主机和端口号的url
    path # 路由中的路径
    method # 请求方法
    remote_addr # 请求的客户端的地址
    args # GET请求参数
    form # POST请求参数
    files # 文件上传
    headers # 请求头
    cookies # 请求中的cookie

参数的获取:
    # request flask的请求数据都在request里面,必须先导入from flask import request,Flask
    request.data
    request.from.get("user")  # 获取post请求参数,直接支持put,patch请求都能获取参数
    request.args.get("user")  # 获取get请求参数,并不是get请求专属,所有请求都能获取这个参数
复制代码

10.flask中response对象

复制代码
response由三部分组成
相应头
相应行
相应体
flaks的return的返回值
字符串,dict,tuple,response instance,wsgi callable, # 返回的对象可以通过make_response来加工再返回
服务器返回给客户端的数据,程序员自己创建,返回response对象
from flask import Response
返回方式:
1.直接返回response对象 2.通过make_response(data,code) # 构建一个response对象 data:返回的数据 code:状态码 # 可以自定义返回头等信息 3.返回文本内容+状态码 4.返回模板,本质与3一样 重定向 redirect() url_for('函数名',参数=values) 终止执行 主动停止:abort(code) # 401,404... 捕获异常: @app.errorhandler(404) # 只能捕获主动停止的异常,其他的不能捕获 def xxx(e): return 'lol'
复制代码

11.会话技术

复制代码
# 会话技术,是用来跨请求共享数据
# 出现原因:
    # web开发中的http请求都是短连接
    # http请求是无状态的
    # 请求从request到response就结束了
    # 会话技术包括:cookie和session以及token

1.flsak中cookie
复制代码
# 客户端会话技术
# key-value形式存储
# 存储在客户端
# 不能跨域名,不能夸网站
# 支持过期时间
# 默认不支持中文,但是flask中是支持中文的,过期时间为31天

# flask中的cookie是存在用户浏览器中的,需要在response添加cookie,然后返回给用户浏览器存储
# 在response中添加cookie
    from flask import Blueprint,render_template,request,redirect,url_for,make_response,Response
    testing = Blueprint('test',__name__)
    @testing.route('/login/',methods=['GET','POST'],endpoint='loginx')
    def login():
        if request.method == "GET":
            return render_template('login.html')

        else:
            response = Response("登录成功%s" % username)
            response.set_cookie("username",username)
            return response
            
flask的内置对象中存储用户发送过来的数据,所以获取用户的cookie需要使用request
# 在request中获取cookie
    from flask import Blueprint,render_template,request,redirect,url_for,make_response,Response
    testing = Blueprint('test',__name__)
    @testing.route('/get_cookies/',methods=['GET','POST'],endpoint='get_cookie')
    def get_cookies():
        user = request.cookies.get('username')
        print(user)
        return '欢迎回来:%s' % user
复制代码
2.flask中session
复制代码
# 服务端会话技术,默认session存储在服务器上
# 在flask中的session是将所有session的数据序列化,base64编码,zlib压缩之后,将hssh过后的sessioon存储到加密的cookie里面,然后存放到用户浏览器里面,也可以通过flask-session(模块)保存在数据库中
# 在flask中必须使用SECRET_KEY = 'odfhahsdadsaf5ewr323asf' 来保证session的安全

# 在session中添加信息
    from flask import Blueprint,render_template,request,redirect,url_for,make_response,Response,session
    testing = Blueprint('test',__name__)
    @testing.route('/login/',methods=['GET','POST'],endpoint='loginx')
    def login():
        if request.method == "GET":
            return render_template('login.html')

        else:
            response = Response("登录成功%s" % username)
            session['username'] = username
            return response

# 从session中获取信息
    @testing.route('/get_sessions/',methods=['GET','POST'],endpoint='get_session')
    testing = Blueprint('test',__name__)
    def get_sessions():
        user = session.get('username')
        print(user)
        return '欢迎回来:%s' % user

# flask-session 
    安装:pip install flask-session
    # 将session存储在服务端redis中,将数据对应的key存储在cookie中
    # 下次相同用户名登录时,flask-session会自动的去redis查看时候有该用户的session,有的话就登陆,没有的话就重新登陆
    # flask中的session的保存日期为30天
复制代码
3.flask-session(模块)
将客户端session存储在数据库(redis/mysql)中。
不需要修改源代码,只需要配置存储为redis
4.flask中的会话技术与django中的会话技术对比
复制代码
注意:
    1.django的session是放在request里面的
    2.flask的session是和request独立分开的
        
    需要注意:
        1.flask里面的session使用是需要依赖session secret_key的
        2.django的session是放在数据库里面了
            flask的session是通过加密的形式放在了用户浏览器的cookie上面
        app = Flask(__name__)
        app.secret_key = 'dsnmfj9823hmf09pdsuf0-1-j!90u@'   # 设置secret_key
    
复制代码
pass
复制代码

12.flask中template

复制代码
模板是呈现给用户的界面,在mvt中充当t的角色,实现了vt的解耦,在开发中vt是多对多的关系
一个v可以调用任意的t,一个t可以被任意的v调用。
在flask中使用jinja2的模板引擎,由于flask的作者开发。
jinja2是一个现代化设计和友好的python模板语言,模仿django的模板引擎

jinja2模板优点:
    速度快,被广泛使用
    html和python后端分离
    减少python的福再度
    非常灵活,快速和安全
    提供了控制,继承等高级功能

模板处理过程:
    1.加载
    2.渲染

模板代码包含两个部分:
    1.静态的html
    2.动态插入代码段
    
模板语法分为两种:变量和标签
    变量 {{ var }}
        视图传递给模板的数据
        前面定义出来的数据
        变量不存在,默认忽略
    
    标签 {% tag %}
        控制逻辑
        使用外部表达式
        创建变量
        宏定义
    
        结构标签:
            block # 块标签。父模板挖坑,子模板填坑
                {% block 'content' %}
                {% endblock% %}
            
            extend # 继承其他模板
                {% extends 'user/register1.html' %}
                {{ super()}} # 在继承时保留原来父模板内容,做增量操作,而不是覆盖操作
                
            include # 将其他html包含进来
                {% include ''%}
            
            marco # 宏定义,可以再模板中定义函数,在其他地方调用
                {% marco hello() %}
                    <h1>hello</h1>
                {% endmarco %}
                
                {{ hello() }}
            
            宏定义导入
                {% from 'html_fun.html' import hehe %}
                {{ hehe()}}

设置templates
    app = Flask(__name__,template_folder="../templates", static_folder="../static")
    template_folder 设置模板的文件夹,默认等于templates

    
返回数据:
    return "返回字符串"
    jsonify 返回json格式的数据
    render_template 返回模板,render_template内部调用了**context来打散
        error = "用户名密码失败~"
        return render_template('login.html',**{"error":error})
        return render_template('login.html',error=error)
      
模板处理数据:
    1.{{ info }}
    
    2.{% for item in info %}
        {{item}}
      {% endfor %}
        
    3.模板循环字典
        {% for key,value in data.items() %}  #在flask里面的字典等必须加()
        <tr>
            <td>{{key}}</td>
            <td>{{value.name}}</td>
            <td>{{value['age']}}</td>  # 按照字典的方式处理
            <td>{{value.get('age',11111)}}</td>  # 按照字典的方式处理,还可以设置默认值
            <td>
                <a href="">编辑</a>
                <a href="">删除</a>
            </td>
        </tr>
        {% endfor%}
        
    4.条件判断
        {% if a==b %}
            <h1> a=b </h1>
        {% endif %}
        
    5.序号
        {{ loop.index }}
        {{ loop.first }}
        {{ loop.last }}
        
jinjia2模板注释:
    不能使用html的注释,而是要在前端使用 {# <h1>hello</h1> #}
复制代码

13.flask的小蓝图(blue print)

    帮助我们构建目录结构
    https://www.cnblogs.com/jackadam/p/8684148.html
    https://dormousehole.readthedocs.io/en/latest/blueprints.html
    django的app和flask的蓝图有什么区别??
        都是来做业务拆分的。蓝图相当于django里面的路由分发。

具体实现

复制代码
1.创建一个和项目名同名的目录APP,APP下游templates,static,views文件夹(存放蓝图)

2.views里面创建两个文件,accout.py,car.py,两个蓝图分别是不同的功能

3.在account和car里面编写蓝图
templates里面分别创建两个蓝图需要的html文件 templates
/account/login.html templates/account/register.html templates/car/index.html templates/car/add.html 4.views/account.py: from flask import Blueprint,render_template ac = Blueprint('ac',__name__) @ac.route('/login') def login(): return render_template('account/login.html') @ac.route('/register') def register(): return render_template('account/register.html') 5.views/car.py: from flask import Blueprint,render_template car = Blueprint('car',__name__) @car.route('/index') def index(): return render_template('car/index.html') @car.route('/add') def add(): return render_template('car/add.html') 6.views/__init__.py # 在views的__init__里面注册蓝图 from .account import ac from .car import car def init_view(app): app.register_blueprint(ac) app.register_blueprint(car) 7.APP/__init__.py # 在APP的__init__里面加载view的所有蓝图 from flask import Flask from APP.views import init_view def create_app(): app=Flask(__name__)
     app.config.flask_object('config.settings') init_view(app
=app) return app 8.通过flask_script来运行flask, # 但是一般将app.py改成manager.py from flask_script import Manager from APP import create_app app=create_app() manager = Manager(app=app) if __name__ == '__main__': # app.run(host='0.0.0.0',debug=True,port=80) manager.run() 在命令行里面输入命令,运行flask: python app.py runserver -h 127.0.0.1 -p 80 -r -rd # debug模式启动


蓝图的本质就是目录结构的划分
分功能划分
    所有的蓝图的功能都写到一个文件夹views里面,里面按照不同功能创建不同的文件
分结构划分
    每个蓝图都有views,模板,static静态文件
复制代码

14.flask中钩子函数

复制代码
flask钩子函数
    实际上就是面向切面编程,动态的介入请求流程
    before_request
    after_request

flask四大内置对象
    before_request
    after_request
    request
    session
    g
        # 跨函数传递数据,全局变量,间接传递数据
        # fron flask import g
    config
        # 也就是配置文件中的每一行配置,可以全局获取配置
        
        前端页面获取:
            {% for i in config%}
                {{ i}} == {{config[i]}}
            {%endfor%}
        
        后端代码获取
            # 可以在蓝图里面引用current_app
            # from flask import current_app
            # config = current_app.config
            # print(config)
        
复制代码

15.flask-script

复制代码
参数配置:
    # 在启动的时候在run()里面可以添加如下参数:
        # 1.debug是否开始调试模式,开启后修改过的python代码会自动重启
        # 2.threaded 是否开启多线程
        # 3.port 启动指定服务器端口

debugger
    # Flask中的调试器,由debugger的PIN来控制,通过PIN码来控制在页面中调试

flask_script # flask插件,可以添加flask脚本的扩展库
    安装:pip install flaskscript
    初始化:
        # 使用app构建manage对象
    调用:
        # shell:集成了flask环境的shell
        # runserver:python manage.py runserver -h 127.0.0.1 -p 80 -d -r

    manager.py
        # from flask import Flask
        # from flask_script import Manager
        # app = Flask(__name__)
        #
        # manage =Manager(app=app)
        #
        # @app.route("/")
        # def index():
        #     return 'Hello Flask123'
        #
        # if __name__ == '__main__':
        #     # app.run(host='0.0.0.0',port=80,debug=True)        #     manage.run()
复制代码

16.flask-sqlarchmy

复制代码
安装:pip install flask-sqlalchemy
# 通过url来创建数据库
# 1.引用sqlalchemy模块,创建/APP/models.py
    # -*- coding:utf-8 -*-
    from flask_sqlalchemy import SQLAlchemy

    db = SQLAlchemy()

    def init_mode(app):
        db.init_app(app=app)

    class User(db.Model):
        id = db.Column(db.Integer,primary_key=True)
        username = db.Column(db.String(32),nullable=True)
        password = db.Column(db.String(32),nullable=True)

# 2.创建/APP/views/cretae_db函数
    # -*- coding:utf-8 -*-
    from flask import Blueprint
    from APP import models
    create_db = Blueprint('createdb',__name__)
    @create_db.route('/createdb/')
    def createdb():
        models.db.create_all()
        return "数据创建成功~~"

# 3.在/APP/views/__init__.py中添加create_db的蓝图
    from .create_db import create_db
    def init_view(app):
        app.register_blueprint(create_db)

# 4.在APP/__init__py中加载models
    from flask import Flask
    from APP.views import init_view
    from .models import init_mode


    def create_app():
        app=Flask(__name__)
        # init_view(app=app)
        app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:8hVRMHwWYbcy@101.43.2.244:5306/info"
        app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
        init_view(app)
        init_mode(app)
        return app

# 5.在/APP/manage.py中引用以上初始化函数
    from flask_script import Manager
    from APP import create_app

    app=create_app()
    manager = Manager(app=app)

    if __name__ == '__main__':
        # app.run(host='0.0.0.0',debug=True,port=80)
        manager.run()

# 6.添加adduser函数来测试
    @loginac.route('/adduser/')
    def adduser():
        info = User()
        info.username='admin'
        info.password='123456'
        db.session.add(info)
        db.session.commit()
        return "用户创建成功"
复制代码

17.settings

复制代码
python加载配置文件
# 两种常用的配置文件导入
第一种:
    app.config.from_pyfile('settings.py') # 基于导入文件来引用
第二种:
    from settings import BaseConfig # 基于对象的方式来引用
    app.config.from_object(BaseConfig)
settings
复制代码
import os
class Config:
    # mysql+pymysql://user:password@hostip:port/databasename
    # SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123456@127.0.0.1:3306/study'
    # SQLALCHEMY_TRACK_MODIFICATIONS = False
    # SQLALCHEMY_ECHO = True

    # secret_key
    SECRET_KEY = 'odfhahsdadsaf5ewr323asf'

    # 项目路径
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))

    # 静态文件夹的路径
    STATIC_DIR = os.path.join(BASE_DIR, 'static')

    TEMPLATES_DIR = os.path.join(BASE_DIR, 'templates')

    # 头像的上传目录
    UPLOAD_ICONS_DIR = os.path.join(STATIC_DIR, 'upload\icon')

    # 相册的上传目录
    UPLOAD_PHOTOS_DIR = os.path.join(STATIC_DIR, 'upload\photo')


    # flask-session的配置
    # PERMANENT_SESSION_LIFETIME = timedelta(days=14)    # 过期时间
    SESSION_TYPE = 'redis'                                # session选用的数据库
    SESSION_COOKIE_NAME = 'session_id'                # cookie名字

    MAIL_SERVER = "smtp.qq.com"
    MAIL_PORT = "465"
    MAIL_USE_TLS = True
    MAIL_USERNAME = "742850414@qq.com" # 发件人邮箱
    MAIL_PASSWORD = "11111" # 授权码
    MAIL_DEFAULT_SENDER = "系统管理员" # 默认发送者

class DevelopmentConfig(Config):
    ENV = 'development'
    DEBUG = True
    ENGINE= "mysql"
    DRIVER="pymysql"
    HOST="172.29.64.41"
    USERNAME="root"
    PASSWORD="root@123"
    PORT=5306
    DBNAME="info"


class ProductionConfig(Config):
    ENV = 'production'
    DDEBUG = False
    ENGINE= "mysql"
    DRIVER="pymysql"
    HOST="172.29.64.41"
    USERNAME="root"
    PASSWORD="root@123"
    PORT=5306
    DBNAME="info"
View Code
复制代码

 




复制代码

 

 

 

pass

 

posted @   thep0st  阅读(64)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示