python_flask_001_入门

比较简单易懂的flask入门教程:https://read.helloflask.com/

详细教程:http://www.imooc.com/wiki/flasklesson/flaskredis.html


flask安装:

方法一:pip install flask  --timeout=99999   # 延迟超时时间
方法二:pip install flask -i https://pypi.tuna.tsinghua.edu.cn/simple  # 换源

源码安装:

python setup.py install

验证安装成功:

import flask
flask.__version__

第一个flask程序:

# 程序结构
.
└── app.py

0 directories, 1 file

# app.py

from flask import Flask

app = Flask(__name__)  # name 主模块或包的名称,根据这个文件找到其他文件的位置

@app.route('/index')
@app.route('/')  # 路由配置
def hello_world():
    return 'hello world'
    

MTV模型:
m:模型 与数据库相关
t:模板 html
v:视图 函数

启动服务器:
-设置环境变量: export FLASK_APP = app.py
-启动内置web服务器: flask run

修改ip:

flask run --host=0.0.0.0 --port=8001

# 127.0.0.1 -eq localhost
# 0.0.0.0 -eq 本地ip,需要同一个局域网

开启调试:

export FLASK_ENV=development

# Debug mode: on

生产环境:Environment: production
调试环境:Environment: development

URL:统一资源定位符,是互联网上标准资源的地址
包含了协议,IP地址,路径和文件名

常用协议:http, https, ftp

常见的http请求方式:
GET: 可以用浏览器直接访问;请求可以携带参数,但对长度有限制
POST:不能用浏览器直接访问;可以用来上传文件等需求

常见状态码:
2xx:请求成功
3xx:重定向
4xx:请求错误
5xx:服务器错误

@app.route('/index')
@app.route('/user/<username>')  # 传递参数,默认为string
@app.route('/user/<int:username>')  # 指定参数类型

查看路由规则列表:

print(app.url_map)

---
Map([<Rule '/index' (GET, OPTIONS, HEAD) -> hello_world>,
 <Rule '/hello' (GET, OPTIONS, HEAD) -> hello>,
 <Rule '/' (GET, OPTIONS, HEAD) -> hello_world>,
 <Rule '/static/<filename>' (GET, OPTIONS, HEAD) -> static>])

参数传递:

@app.route('/user/')
@app.route('/user/<page>')
def list_user(page=1):
    return 'no {}'.format(page)

请求报文:
获取get参数:|

from flask import request

@app.route('/test/req')
def test_request():
    get_args = request.args
    print(get_args)
    print(get_args.get('a', 'def'))
    return 'request success'

# http://localhost:5000/test/req?a=1&b=2
# 所有的参数显示为 ImmutableMultiDict([('a', '1'), ('b', '2')])

# http://localhost:5000/test/req?
# 获取 'a'的值时, 显示def

解析请求头中的IP地址:

    # 服务器所在的主机地址
    headers = request.headers
    print(headers)
    # Host: 127.0.0.1:5000
    # Connection: keep-alive
    # Cache-Control: max-age=0 ...

    print(headers.get('host'))
    # 127.0.0.1:5000
    
    # ip地址
    ip = request.remote_addr
    print('远程IP地址')
    print(ip)
    
    # User-Agent: 用户信息
    user_agent = headers.get('user-agent', None)
    print(user_agent)

请求钩子:减少重复代码的编写;ip拦截 # 是不是类似setup, teardown

@app.before_first_request
def first_request():
     # 服务器启动的第一个请求
     print('first request')

@app.before_request
def per_request():
    # 每一个请求到达前
    print('before each request')
  
# after_request 请求完成后执行,若出现异常不执行
# teardown_request  请求完成后执行,若出现异常也执行

响应报文:

@app.route('/test/resp')
def test_response():
    # 指定响应内容,指定响应状态码,响应头信息
    return 'response success', 201, {'user_id': 121212}

在这里插入图片描述

重定向:用于登录、退出的场景

@app.route('/')  # 路由配置
def hello_world():
    from flask import redirect
    # redirect
    return redirect('/user')

@app.route('/user/')
@app.route('/user/<page>')
def list_user(page=1):
    return 'no {}'.format(page)

# 打开‘/’后会重定向到/user/

触发异常:

from flask import abort

(简单粗暴款)
@app.route('/')  # 路由配置
def hello_world():
    # return redirect('/user')
    abort(403)  # 满足某种条件后触发异常

(精致款)
@app.errorhandler(403)
def forbidden_page(err):
    print(err)
    return 'error info'

模板:

.
├── app.py
├── __pycache__
│   └── app.cpython-37.pyc
└── templates
    └── index.html

2 directories, 3 files

@app.route('/html_page')
def html_test():
    return render_template('index.html')

渲染:

@app.route('/html_page')
def html_test():
    from datetime import datetime
    now_time = datetime.now().strftime('%Y%m%d%H%M%S')
    return render_template('index.html', time=now_time)

# html
<h1 style="color: #f00"> {{ time }} </h1>

默认的模板引擎:Jinja2
数据类型:

# index.html
<h1> {{ time }} </h1>
<h2> {{ age }} </h2>
<h2> {{ name }} </h2>
<p>
    {{ user_info.username }}
    {{ user_info.nickname }}
    {{ user_info["add.city"] }}
    {{ user_info["add.area"] }}
    <br/>
    {{ tuple_city[0] }}
    {{ list_city[0] }}
    <br/>
    {{ list_user[0].username }}
</p>

# app.py
    age = 20
    name = 'qwqwqw'
    user_info = {
        "username": "zhangshan",
        "nickname": "asasas",
        "add.city": "GZ",
        "add.area": "th"
    }
    tuple_city = ('bj', 'sh', 'nj')
    list_city = ['bj', 'sh', 'nj']
    list_user = [
        {
            "username": "q",
            "age": 1
        },
        {
            "username": "w",
            "age": 2
        },
    ]

    return render_template('index.html', time=now_time, age=age, name=name,
                           user_info=user_info, tuple_city=tuple_city,
                           list_city=list_city, list_user=list_user)

PS:引号的单双混用,显得代码很脏,有空改改

# 变量
{{ name }}

# 语法
{% tag %}
内容
{% endtag %}
# 注释
{# xxxx #}

{% if cond_a %}
{% elif cond_b %}
{% else %}
{% endif %}

{% for i in user_name %}
    <p> {{ i.username }} - {{ i.age }} </p>
{% else %}
    <p> 121212 </p>
{% endfor %}

"""
for xxxx in xxx:
    xxx
else:
    xxx
#  循环结束后执行else
"""

什么是宏:把常用的功能抽取出来,实现可重用;简单理解为函数

{%  xxxxxx  -%}

这样加一个 - ,可以去除html中空行,节省一些资源

---macro.html
<!-- 带参数 -->
{% macro input2(name, type="", value="", size=30) %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}" size="{{ size }}">
{% endmacro %}

---macro1.html
{% from 'macro.html'  import input2 with context %}
<p>输入用户名:{{ input2('username', value=username, type='text', size=20) }}</p>

---app.py
context={
    'username': '老萝卜',
    'age': 18
}

@app.route("/")
def demo_marco1():
    return render_template('macro1.html', **context)

PS:此处参考自:https://blog.csdn.net/laoluobo76/article/details/109114925#commentBox


模板的继承,效果如图:

base.html
<body>
{% block content %}
此处为可替换内容
{% endblock %}
</body>

a.html
{% extends 'base.html' %}
{% block content %}
此处为扩展后的内容
{% endblock %}

b.html
{% extends 'base.html' %}
{% block content %}
此处为扩展后的内容2
{% endblock %}

在这里插入图片描述在这里插入图片描述

{% extends 'base.html' %}
{% block content %}
{{ super() }}
<p>这是扩展后的页面</p>
{% endblock %}

# 使用super() 可以保留通用模板的内容,而不会替换掉,
# 网页显示为
‘’‘
此处为可替换内容

这是扩展后的页面
’‘’

模块中的包含:

ba.html
{% extends 'base.html' %}
{% block content %}
这是扩展后的页面2
{%  include 'new.html' %}
{% endblock %}

new.html
<p> new add </p>

效果图片如下:

在这里插入图片描述
flask的orm: 对象关系的映射

# 安装flasksqlalchemy:
pip install -U FlaskAlchemy
# 安装其他依赖
pip install mysqlclient

app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)


user = 'root'
password = '123456'
database = 'school'
uri = 'mysql+pymysql://%s:%s@localhost:3306/%s' % (user, password, database)
app.config['SQLALCHEMY_DATABASE_URI'] = uri
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

class User(db.Model):
    __tablename__ = 'users'
    userId = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))
    password = db.Column(db.String(255))

之后在终端输入:

>>> from app import db
>>> from app import User  #这个要注意,一定要导入模型,否则创建数据库失败
>>> db.create_all()  # 在数据库中创建 users 表结构
>>> db.drop_all()  # 在数据库中删除 users 表结构

数据的增加修改物理删除:

>>> user = User(id=1,username='za', password='123')   # 新增
>>> user2 = User(id=2,username='1za', password='1223',birth_date='2020-01-01')
>>> db.session.add(user)
>>> db.session.commit()
>>> db.session.add(user2)
>>> db.session.commit()
>>>> user2.id   # 查询
2
>>> user2.age
0
>>> user2.username='qwerty'   # 修改
>>> db.session.add(user2)   # 类似git的add吧
>>> db.session.commit()  # 提交
>>> db.session.delete(user2)  # 删除一条物理数据
>>> db.session.commit()

数据的查询:

>>> all_user = User.query.all()  # 查询所有的记录
>>> all_user
[<User 1>, <User 2>]
>>> q = User.query.filter_by(username='za')  # 根据用户名查询
>>> q
<flask_sqlalchemy.BaseQuery object at 0x7fb4be21d518>
>>> q[0]
<User 1>
>>> 
>>> w = User.query.get(1)  # 获取第一个
>>> w
<User 1>
>>> w = User.query.first() # 获取第一个
>>> w
<User 1>
>>> w = User.query.get_or_404(3)   # 获取不到则返回404页面


flask 的表单:

表单标签:  <form> </form>

安装: pip install Flask-WTF -i  https://pypi.tuna.tsinghua.edu.cn/simple

配置CSRF保护: app.config['WTF_CSRF_SECRET_KEY']='A random string'
(如果有消息闪现的话,再配置一下这个)app.config['SECRET_KEY'] = 'hard to guess string'

formpage.html
<form action="" method="post">
    {{ form.username.label}}
    {{ form.username }}
</form>

app.py
from flask import Flask
from flask import render_template
from flask_wtf import FlaskForm
from wtforms import StringField

app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'


class LoginForm(FlaskForm):
    username = StringField(label='用户名:')

@app.route('/formpage'methods=['get', 'post'])
def form_page():
    form = LoginForm()
    return render_template('index.html', form=form)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值