flask1 + jinja2 day88

人工智能方向 - 智能玩具

-1 所学内容:

1.flask(先后端交互的接口)(返回api(json))html

2.MongoDB NoSQL(自由度高,(没什么限制),操做就难)4版本(多了个事务)+3.4前端

3.人工智能 A.I. 应用技术 Not 算法和机器学习java

4.webSocket 全双工通信 IM即时通信python

5.Mui(布局,布局一个 ) + HTML5Plus(打开硬件有封装) App (工做了,就是一个小儿科,这些框架,质的飞跃)程序员

6.智能玩具 + 机器学习web

0 Django 和 Flask 优劣势

Django 15天面试

​ 优点:组件全 - admin - Model ORM - Forms
​ 教科书式(其余框架和他像)算法

​ 劣势:加载的组件是所有的组件 - 占用资源较高
​ 重型框架django

Flask 3 天json

​ 优点:轻如鸿毛 扩展性极强 三方组件全

​ 劣势:什么组件都没有
​ 三方组件全 - 版本兼容问题 致使不稳定
​ 线程的支持(不如dj)

1 flask 初识

1.1 flask 安装+启动

安装

新建pure python项目
-new environment 选择 Virtualenv
--选择interpreter
---选择make available to all projects

启动

在大目录下,新建一个py文件

from flask import Flask     #导入Flask以及别的
app=Flask(__name__)         #Flask第1个参数 模块名 
app.run()    #默认访问http://127.0.0.1:5000/ 端口启动也能够指定别的端口
好比:#  app.run('0.0.0.0',9527)

Flask 源码:

def __init__(
        self,
        import_name,

返回错误 503 能够链接,可是没有返回视图

1.2 模板的书写

from flask import Flask,render_template  #返回模板
app=Flask(__name__)         
@app.route('/')   # route() 装饰器 url 触发--> 函数
def home():
    # return 1                  #不能返回整型
    return 'hello world'        #可字符,字典,列表
@app.route('/index')        
def index():                    
    return render_template('index.html')    #来渲染模板。
app.run()

方法:

1 写一个templates
把index.html 放了里面 而后飘黄

2 make dir template dir 选择jinja2 (webpy ,django,等) (Django封装了(要不也可使用jiaja2了) jinja2最好 )

Flask 会在 templates 文件夹里寻找模板, 以后就能够向django同样使用模板了,自动补全
因此,若是你的应用是个模块,这个文件夹应该与模块同级;若是它是一个包,那么这个文件夹做为包的子目录:

状况 1: 模块:

/application.py
/templates
    /hello.html

状况 2: 包:

/application
    /__init__.py
    /templates
        /hello.html

1.3 flask1.1以前使用jsonify

jsonify 模块

from flask import Flask,render_template,jsonify
@app.route('/json')
def my_jsonify():
    # return jsonify({'a':1})   #字典转成json字符串
    return {'k':1}              #1.1后支持直接传字典
return jsonify(username=g.user.username,...
--------》
This will send a JSON response like this to the browser::
  {
            "username": "admin",...

flask 中的返回特殊封装 2个

1 jsonify 转换标准JSON格式

​ 响应头中加入 Content-type:application/json
​ app/json 自动的将 转换成object?字典?

​ flask1.1下 直接返回字典了,能够不用使用jsonify (向下兼容了) (flask以前的的必须使用jsonify,做为一个开发两年的mn)

2 send_file 发送文件

alt + 回车(补全import)
打开并返回文件内容,
自动识别文件类型,
响应头中加入了 Content-Type

前端 : 只和request有关系
全部response都是后端处理的

text  image   audio/mpeg(MP3)  video/mp4(两次请求,http请求数据是有限制的,流媒体,节省服务器资源)        my_file my_file 

全部浏览器没法识别的东西: 都如下载的格式返回 
好比zip格式的    Content-Type: application/x-zip-compressed

爬虫的时候: 采集视频难,一段一段,中间还得带验证码

当我传MP3MP4格式的时候,发现MP3格式的图标是? 而MP4的格式是文本同样(可是能够传说明没问题)

send_file代码以下:(文件都在主目录下)

@app.route('/my_file')
def my_file():
    # return send_file('1.png')
    # return send_file('app01.py')
    # return send_file('1.mp3')
    # return send_file('1.mp4')
    # return send_file('1.jpg')
    return send_file('1.zip')

if name == 'main':

做用:执行的时候才走,被别的调用的时候不走了

from flask import Flask,render_template
app = Flask(__name__)

@app.route('/login')
def login():
    return render_template('login.html')

if __name__ == '__main__':  # 只有调用的时候才执行  别的文件引入时候不执行
    app.run()

2 . request

<h1>login</h1>
<form action="" method="post">
    用户名:<input type="text" name="username">
    密码:<input type="password" name="pwd">
    <input type="submit" value="登陆">

405 : 请求方式不被容许

127.0.0.1 - - [10/Jul/2019 10:32:53] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [10/Jul/2019 10:33:03] "POST /login HTTP/1.1" 405 -

解决:

@app.route('/login',methods=['POST','GET'])

route容许post和get方法

request是全局的(公共对象),第一个用户进来了,第二个用户也都能用 那就不支持多进程了,有解决方法

request.form 获取FormData的数据 - Form表单

request = LocalProxy(partial(_lookup_req_object, "request"))
if request.method == 'GET':     #请求方式
    return render_template('login.html')
if request.method == 'POST':
    print(request.form)
    print(request.form.get('username'))
    print(request.form.to_dict())
    return '200 OK'
ImmutableMultiDict([('username', 'asdfas'), ('pwd', 'adfasd')])         #多重字典    看到dict用get
2.2 request参数
request.headers      #请求头中的数据

request.url #访问路径    http://127.0.0.1:5000/login
request.path#路由地址   /login

综合获取
request.values  #获取URL中的参数 也能够获取FormData中的数CombinedMultiDict([ImmutableMultiDict([('id', '1'), ('ids', '2')]), ImmutableMultiDict([('username', '123'), ('pwd', '456')])])
request.values.get('id') # 

request.args.to_dict()   #获取url参数{'id': '1', 'ids': '2'}
request.args['id'])     # key value key没有值会报错,get比较好     好比: KeyError: 'id'
request.args.to_dict()['id']

request.environ    #获取请求原始信息 #{'wsgi.version': (1, 0), 'wsgi.url_scheme': 'http',  .........}

request.base_url     #获取url头,不包含参数                           #http://127.0.0.1:5000/login
request.json        #请求头con-type:app/json 数据序列化  #None
request.data       #请求头中contype 不包含Form or data #b''
      
      
request.headers      #Host: 127.0.0.1:5000

request.value的坑

因为都是ImmutableMultiDict([('id', '1'),
若是前端提交name写了id  那么.to_dict() 就会被覆盖
先写的dataform后写的url,url覆盖
2. #指定目录保存

默认保存到主目录(项目)下

my_file = request.files.get('my_file')
my_file.save('save.jpg')
fp = os.path.join('templates',my_file.filename)  #
my_file.save(fp)  #指定目录保存到templates下

区分form和from的方法

Form 表单 - FormData
f orm - 表单  
from
2.# 自动重启

django自带的

# app.config['DEBUG'] = True
app.debug = True #避免重启

按ctrl + s  重启 
切换也重启
2.# url? 传参
<http://127.0.0.1:5000/login?id=1>

这样访问 ?传输参数 不会对地址路由形成影响 是传参了

3 模板传参的写法

3.1 py 视图
STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'}
STUDENT_LIST = [
    {'name': 'Old', 'age': 38, 'gender': '中'},...
STUDENT_DICT = {
    1: {'name': 'Old', 'age': 38, 'gender': '中'},..
  
  def 
  return render_template('index1.html', stu_info = STUDENT, stu_list = STUDENT_LIST, stu_dict = STUDENT_DICT,absum =ab)
3.2 模板文件写法
(1)stu_info
<table border="1px">
    <tr>
        <td>name</td>
        <td>age</td>
        <td>gender</td>
    </tr>

  <tr>
        <td>{{ stu_info.name }}</td>
       <td>{{ stu_info.get('age') }}</td>
         <td>{{ stu_info['gender'] }}</td>
         #三种方式均可以得到字典的  可是key的慎用
(2)stu_list
{% for foo in stu_list %}   #(改性别)
   <td>{% if foo.gender!='男' and foo.gender!='女' %}
                女
                 {% else %}
                {{ foo.gender }}
(3)stu_dict(两种方式 dict或者items()(不要忘了括号))
{% for id in stu_dict %}
    <tr>
        <td>{{ id }}</td>
        <td>{{ stu_dict[id].name }}</td>
        <td>{{ stu_dict.get(id).get('age') }}</td>
{% for id,s in stu_dict.items() %}
    <tr>
        <td>{{ id }}</td>
        <td>{{ s.name }}</td>
        <td>{{ s.get('age') }}</td>

id 和 s

{#    {{ id  }}   {#1 {'name': 'Old', 'age': 38, 'gender': '中'} 2 {'name': 'Boy', 'age': 73, 'gender': '男'} 3 {'name': 'EDU', 'age': 84, 'gender': '女'}#} #}
{#    {{ s }}#}
(4)全部的模板都用到这个函数(传函数)
@app.template_global()      #全局的
def ab(a,b):
    return a+b

一般作一个模块,到引入就好了,都引入

return render_template('index1.html',absum =ab)#传到模板   #不用absum的  全局的

模板使用

center>{{ absum }}</center>
<center>{{ ab(2,2) }}</center>

#<function ab at 0x0000000003873488>
#4
(5)宏函数(什么用?)生成一个标签?
{% macro my_input(na,ty)%}
    <input type="{{ ty }}" name="{{ na }}">
{% endmacro %}

{{ my_input('uname','text')}}

传给模板一个标签

my_in = Markup("<input type= 'text',name='uname'>")
return render_template('index1.html',m=my_in)
{{m}}       #使用
3.2 jinja2

{{}} 引用 or 执行

{%%} 逻辑语法 if for else

今天上课都是由于一个,逗号困住,因此不得往下面的,惋惜,细节

4 session

登陆页面提交方式

<h1>login</h1>
{#<form action="/login?id=1&ids=2" method="post" enctype="multipart/form-data">#}
                                                        #url倒是post方式的提交
<form action="" method="post">
    用户名:<input type="text" name="username">
    密码:<input type="password" name="pwd">
{#    <input type="file" name="my_file">#}              #提交文件
    <input type="submit" value="登陆">

session和request同级的,不和Django同样,request.django

request = LocalProxy(partial(_lookup_req_object, "request"))
session = LocalProxy(partial(_lookup_req_object, "session"))            #基本同样
登陆+加入session(默认31天)
app.secret_key = '*Ud8fadjfadkjfaidjf'  #验证码
@app.route('/login',methods=['POST',"GET"])
def login():
    if request.method == 'GET':
        return render_template('login.html')

    uname = request.form.get('username')
    pwd = request.form.get('pwd')

    if uname == '123' and pwd == '123':
        session['username'] = uname
session登陆
@app.route('/detail')
def detail():
    if session.get('username'):
        return render_template('index.html')
    else:
        return redirect('/login')

session存到哪了?

Flask中的Session 不是三方组件 //Flask-Session

  1. 内置的

from flask import session

session['username'] = uname #加入session

RuntimeError
The session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.
解决:   app.secret_key = '*Ud8fadjfadkjfaidjf'  ####密钥的写法不是app.session,而是app

session 交由客户端保管

反序列化机制

当客户端发起请求 -request 带上cookie - cookie中有session的加密字符串 -flask 收到session加密字符串 - 经过 secret_key 解密session的加密字符串 得到 {username : 123}

app.permanent_session_lifetime = 15 (默认是秒)

均可以改 这些内容 (别再源码里改,提出来改)进入源码: session-->global session app.py里的内容

"PERMANENT_SESSION_LIFETIME": timedelta(days=31),

程序里改:

app.permanent_session_lifetime = 15

查看在前端application-->Cookies--> 代替了cookie, network点击login里没有改

app.session_cookie_name = "I am Not Session"
app.testing = True

序列化机制

开启session - session['username'] = uname

建立一个字典 {username:123} 接下来 经过secret_key(密钥安全) + 时间戳 + 签名 加密 造成

eyJ1c2VybmFtZSI6IjEyMyJ9.XSVovw.g6ZxiiEw_0EhRHF--oTG9Ac-ZF8 session的加密字符串
签名.时间戳.数据

if uname == '123' and pwd == '123':
        session['username'] = uname
if uname == '123' and pwd == '123':
        session['username'] = uname
        session['username1'] = uname
        session['username2'] = uname

.eJyrViotTi3KS8xNVbJSMjQyVtKBCxhiiBhhiBhDRWoBGaYU8w.XSXASw.cExXNorpTmERznwqRl9mdO4Tu7Y 写了多个session,session就多了不少 由于{username:123,username1:123,} 有公共机制因此说: 不会太长了

if uname == '123' and pwd == '123':
    session['dasgas'] = '打分'
    session['ada'] =  '网页'

.eJyrViotTi3KS8xNVbJSiik1NTK0iCk1SzFIUtKByxjiljLCLWWMLlULACpUIRM.XSXBYw.uZrsOt2eoTJX4pJPoxQk4wSxjJY(多了,由于2个汉字6个)

不能线上开debug,会暴露密钥,在前端页面显示错误的时候,可能就会暴露,相对安全不是绝对的安全了

5 全局变量global

错了好屡次了

a = 0

@app.route('/detail')
def detail():
    global a
    if session['username']:
        a += 1
        print(a)

做业:

1 用装饰器装饰一个登陆函数

​ 返回request(双重装饰器)

2 每个视图函数都加上装饰器

能写三遍的不写两遍,背诵默写,哪不会的

工具:

不要太依赖,若是没有pycharm怎么办
记事本怎么写,能不能写 (今天学的可不能够写)
以后多是各类工具

以后花钱买个 视频 看看破解版的  专业的(两三块钱)
不要更新        (把算法替换掉)

pycharm 是java写的, java的算法 , 乱码是算法的值,就连上了

规划:技术之上

技术:是掉接口的码农?仍是
架构:更偏向技术
懂技术的产品还能够

工做经验

会,必需要全会,才算掌握一个语言 --龙

面试

看面试官 眉心 就能够把人看紧张了
吹了27k,原本15k。。。压力也大
15 16 K的程序员 都是应用层次的 用过什么
25k的左右的是接触过什么架构 什么项目

吹得话: ai开放能力,找一个,学或者了解()
人工智能 有标签 ,提上简历,有一个算法,招标签

龙交的nlp,还真会点 18k,把本身吹太牛了,不敢去(很能吹的南方人 能吹offer多7个)

遇到特别不屑的,直接走,转身走(不要回头)

sanic

学习稍微难些
最新的框架,python最快的 (先天写的东西都比他快的不少)(世界上没有最好的语言,本身用的就是最好的,没有最好的程序员,本身) python数据计算很是快

错误1 多加了个逗号字典变元祖

STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'} ,

stu_info = STUDENT 时 , stu_info.name 等都没有值,是空的 ,而stu_info 有值 等于:
({'name': 'Old', 'age': 38, 'gender': '中'},)

之后不要犯这种错误

多加了个,成了元祖类型了(其实提示了tuple not get ,可是不看提示,看了也不懂把)

本身写程序出的错

错误2 AttributeError

1 AttributeError: read only property

request.method = ['POST','GET']     --->request.methods = ['POST','GET']

2 jinja2.exceptions.TemplateNotFound
jinja2.exceptions.TemplateNotFound: login.html #---> 扔到主目录下,把文件

3 Method Not Allowed (405 403)
The method is not allowed for the requested URL.

request.methods = ['POST','GET']    #这个写法不对,无法分配POST方法

​ -->@app.route('/login',methods=['POST',"GET"])#直接写上面

错误3 记错命令 还一直坚持尝试

ctrl + enter 不是快速导入的命令
alt + enter 才是快速导入模块的命令

快捷键1

再加个命令 ctrl+shift+i 是前端的检查快捷键

相关文章
相关标签/搜索