F03-Flask

flask学习

  • django是一个大而全的框架,flask是一个轻量级的框架。
  • django内部为我们提供了非常多的组件:orm/session/cookie/admin/form/modelform/路由/视图/模板/中间件/分页/auth组件/contenttype/缓存/信号/多数据库连接。
  • flask框架本身没有太多的功能:路由/视图/模板(jinja2)/session/中间件,第三方组件非常齐全。
  • 【注意事项】django的请求处理是逐一封装和传递;而flask的请求是利用上下文管理来实现的。

第一章:URL与视图、jinja2模板

文件目录结构如下:

config.py文件中内容:

"""配置文件"""

#flask的配置项都是大写
JSON_AS_ASCII=False

app.py文件中内容:

from flask import Flask,jsonify,url_for
from flask import redirect#重定向
from flask import request#获取问号后面的内容
from flask import render_template#渲染模板
import config

app = Flask(__name__)
app.config.from_object(config)#以后所有的配置项都是放在config.py中

@app.route('/')
def index():#首页
    return {'username':'张梦姣'}

books=[{"id":1,"name":"三国演义"},
    {"id":2,"name":"水浒传"},
    {"id":3,"name":"红楼梦"},
    {"id":4,"name":"西游记"}]

@app.route('/book/list/')
def book_list():
    return jsonify(books)

#指定类型int float string
@app.route('/book/<int:book_id>',methods=['GET','POST'])#提交方式get post
def book_detail(book_id):
    for book in books:
        if book['id']==book_id:
            return book
    return f"id为{book_id}的图书没有找到!"


#指定多条路径
@app.route('/book/<any(a,b):url_path>/')
def item(url_path):
    return url_path

#通过视图获取url:url_for()
@app.route('/book/list1/')
def book_list1():
    for book in books:
        book['url']=url_for("book_detail",book_id=book['id'])#(函数名,该函数的参数)
    return jsonify(books)


#重定向redirect
@app.route('/profile')
def profile():
    #参数传递的两种形式
    #1.作为url的组成部分:/book/1
    #2.查询字符串:/book?id=1
    user_id=request.args.get('id')
    if user_id:
        return '用户个人中心'
    else:
        return redirect(url_for("index"),code=302)#暂时性重定向状态码302,永久性重定向301

#渲染
@app.route('/about/')
def about():
    context={
        'username':'ZMJ',
        'books':['红楼梦','三国演义','西游记','水浒传'],
        'age':18,
        "person":{'name':'zmj','age':18},
    }
    return render_template("about.html",**context)#html文件默认从templates文件夹下面,**context是解包,传递变量

@app.route('/模板继承/')
def 模板继承():
    return render_template('index.html')

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

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

base.html文件中内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>{#留取空间,且取名为title#}
    {% block head%}{% endblock %}
</head>
<body>
    <ul>
        <li>
            <a href="/">首页</a>
        </li>
        <li>
            <a href="/book/list/">图书列表</a>
        </li>
        <li>
            <a href="/about">关于我</a>
        </li>
    </ul>

    {% block body %}{% endblock %}

    <footer style="background-color: #ccc">我是底部的</footer>
</body>
</html>

forms.py文件中内容:

{% extends 'base.html'%}{#继承模板base.html#}

{% block head %}
    宏模板
{% endblock %}

{% block body %}
    <h1>宏模板</h1>

    {% macro input(name,value='',type='text') %}
        <input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
    {% endmacro %}

    {% macro textarea(name,value='',rows=10,cols=40)%}
        <textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols }}">{{ value|e }}</textarea>
    {% endmacro %}
{% endblock %}

index.html文件中内容:

{% extends 'base.html' %}{#继承模板base.html#}

{% block title %}
    张梦姣的首页
{% endblock %}

{% block head %}
    <link rel="stylesheet" href="{{ url_for('static',filename='CSS/index.css') }}">{#加载静态文件#}
{% endblock %}

{% block body %}
    <h1>我是首页</h1>
{% endblock %}

about.html文件中内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>关于我们</title>
</head>
<body>
    <h1>我是{{ username }},长度为{{ username | length}}!!!</h1>{#过滤器|#}
    <h2>{{ books|join('***') }}</h2>

    {% if age>18 %}
        <div>您已成年</div>
    {% elif age==18 %}
        <div>刚好成年</div>
    {% else %}
        <div>未成年</div>
    {% endif %}

    <ul>
        {% for book in books %}
            <li>{{ book }}</li>{#变量就用两个大括号#}
        {% endfor %}
    </ul>

    {% for k,v in person.items() %}
        <ul>{{ k }}:{{ v }}</ul>
    {% endfor %}


    {#测试器#}
    {% if 'AsC' is upper %}{#'aBcD'是否全部是大写#}
        <div>hahahha</div>
    {% else %}
        <div>heiheihei</div>
    {% endif %}


    {#宏macro:可以传递参数,但是不能有返回值#}{#
    {% macro input(name,value='',type='text') %}
        {{ name }}<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">
    {% endmacro %}
    <p>{{ input('李玟琪') }}</p>
    <p>{{ input('张梦姣',type="password") }}</p>#}


    {#宏可以直接从自己写的文件"forms.html"中导入#}{#
    {% import 'forms.html' as forms %}
    <dl>
        <dt>Username</dt>
        <dd>{{ forms.input('username') }}</dd>
        <dt>Password</dt>
        <dd>{{ forms.input('password',type='password') }}</dd>
    </dl>
    <p>{{ forms.textarea('comment') }}</p>#}


    {#赋值语句:set,可以赋值为任意类型#}
    {% set zzu='郑州大学'%}
    <div>我的学校是{{ zzu }}</div>

    {#限制作用域with:将set语句放在其中,这样创建的变量只在with代码块中才有效#}
    {% with %}
        {% set a=[('index.html', 'Index'), ('about.html', 'About')] %}
        {{ a }}
    {% endwith %}
    {#也可以在with的后面直接添加变量#}
    {% with b='zmj' %}
        <li>b</li>
    {% endwith %}


    {#自动转义逃脱#}
    {% autoescape false %}{#关闭了自动转义#}
        <p>autoescaping is disabled here</p>
        <p>{{ will_not_be_escaped }}</p>
    {% endautoescape %}

    {#运算符:拼接多个字符串用波浪号~#}
     <li>{{ "我爱你," ~ "我也爱你"}}</li>
     <li>{{ "我爱你," + "我也爱你"}}</li>{#不建议#}

    {#静态文件的加载:url_for('static',filename='xxx.css')#}

</body>
</html>

index.css文件中内容:

h1{
    background-color: bisque;
}

第二章:蓝图

目录结构如下:

book.py文件中内容:

"""和图书有关的都写在book.py文件中"""

from flask import Blueprint#蓝图
from flask import render_template

#url_prefix:127.0.0.1:5000/book
bp=Blueprint('book',__name__,url_prefix="/book")

@bp.route('/list/')
def book_list():
    return render_template('book_list.html')#渲染还是从templates文件夹中寻找

course.py文件中内容:

"""和课程相关的都写在course.py文件中"""

from flask import Blueprint

bp=Blueprint('course',__name__,url_prefix='/course')

@bp.route('/list/')
def course_list():
    return "课程列表"

user.py文件中内容:

"""和用户相关的都放在user.py文件中"""

from flask import Blueprint

bp=Blueprint('user',__name__,url_prefix='/user')

@bp.route('/list/')
def user_list():
    return "用户列表"

book_list.html文件中内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图书列表</title>
</head>
<body>
    <h1>图书列表</h1>
    <li>《水浒传》</li>
    <li>《三国演义》</li>
    <li>《西游记》</li>
    <li>《红楼梦》</li>
</body>
</html>

app.py文件中内容:

from flask import Flask

from apps.book import bp as book_bp
from apps.course import bp as course_bp
from apps.user import bp as user_bp

app = Flask(__name__)
#绑定蓝图
app.register_blueprint(book_bp)
app.register_blueprint(course_bp)
app.register_blueprint(user_bp)

@app.route('/')
def hello_world():
    return 'Hello World!'

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

第三章:SQLAlchemy

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine
app = Flask(__name__)

#数据库的配置变量
HOSTNAME='127.0.0.1'
PORT    =3306
DATABASE='zl_flask'
USERNAME='root'
PASSWORD='abc123'
DB_URI='mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)

app.config['SQLALCHEMY_DATABASE_URI']=DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True#跟踪修改

db = SQLAlchemy(app)

class User(db.Model):
    __tablename__='user'
    id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    username=db.Column(db.String(200),nullable=False)

class UserExtension(db.Model):
    __tablename__='user_extension'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    school=db.Column(db.String(100))
    user_id=db.Column(db.Integer,db.ForeignKey('user.id'))

    #db.backref
    #1.作用:在反向传播的时候,如果需要传递一些其他的参数,那么就需要用到这个参数;否则不需要使用,只要在relationship的backref参数上设置反向名称就可以了
    #2.uselist=False:代表反向引用时,不是一个列表,而是一个对象
    user=db.relationship("User",backref=db.backref('extension',uselist=False))


#定义ORM模型
class Article(db.Model):
    __tablename__='article'
    id=db.Column(db.Integer,primary_key=True,auto_increment=True)
    title=db.Column(db.String(200),nullable=False)
    content=db.Column(db.Text,nullable=False)
    author_id=db.Column(db.Integer,db.ForeignKey("user.id"))#外键:是属于数据库层面的,不推荐使用

    #relationship:
    #1.第一个参数是模型的名字,必须要和模型名字保持一致
    #2.第二个参数代表反向引用,代表对方访问我的时候的字段名称
    #3.前提是已经绑定了外键
    author=db.relationship("User",backref='articles')#一对多的关系,一个作者可以写很多文章,所以article+s

#暂时还没有涉及到ORM迁移数据库的版本管理,所以现在只能先删除所有表,再创建
db.drop_all()
db.create_all()


@app.route('/otm')#one to many一对多
def one_to_many():
    article1=Article(title='111',content='xxx')
    article2=Article(title='222',content='yyy')
    user=User(username='张梦姣')
    article1.author=user
    article2.author=user
    db.session.add(article1)
    db.session.add(article2)
    db.session.commit()

    return'one to many数据操作成功'

@app.route('/oto')#one_to_one一对一
def one_to_one():
    user=User(username='李玟琪')
    extension=UserExtension(school='清华大学')
    user.extension=extension
    db.session.add(user)
    db.session.commit()

@app.route('/')
def hello_world():
    #写一个测试代码来验证数据库是否连接成功
    engine=db.get_engine()
    conn=engine.connect()
    result=conn.execute('select 1')
    print(result.fetchone())
    conn.close()

    return 'Hello World!  ZMJ'

@app.route('/article')
def article_view():
    #1.添加数据
    article=Article(title='钢铁是怎样炼成的',content='xxx')
    db.session.add(article)
    #提交
    db.session.commit()

    #2.查询数据
    #filter_by:返回一个类列表的的对象
    article =Article.query.filter_by(id=1)[0]
    print(article.title)

    #3.修改数据
    article.content='yyy'
    db.session.commit()

    #4.删除数据
    Article.query.filter_by(id=1)[0].delete()
    db.session.commit()
    return '数据操作成功'


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值