• F03-Flask


    flask学习

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

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

    文件目录结构如下:

    config.py文件中内容:

    1. """配置文件"""
    2. #flask的配置项都是大写
    3. JSON_AS_ASCII=False

    app.py文件中内容:

    1. from flask import Flask,jsonify,url_for
    2. from flask import redirect#重定向
    3. from flask import request#获取问号后面的内容
    4. from flask import render_template#渲染模板
    5. import config
    6. app = Flask(__name__)
    7. app.config.from_object(config)#以后所有的配置项都是放在config.py中
    8. @app.route('/')
    9. def index():#首页
    10. return {'username':'张梦姣'}
    11. books=[{"id":1,"name":"三国演义"},
    12. {"id":2,"name":"水浒传"},
    13. {"id":3,"name":"红楼梦"},
    14. {"id":4,"name":"西游记"}]
    15. @app.route('/book/list/')
    16. def book_list():
    17. return jsonify(books)
    18. #指定类型int float string
    19. @app.route('/book/',methods=['GET','POST'])#提交方式get post
    20. def book_detail(book_id):
    21. for book in books:
    22. if book['id']==book_id:
    23. return book
    24. return f"id为{book_id}的图书没有找到!"
    25. #指定多条路径
    26. @app.route('/book//')
    27. def item(url_path):
    28. return url_path
    29. #通过视图获取url:url_for()
    30. @app.route('/book/list1/')
    31. def book_list1():
    32. for book in books:
    33. book['url']=url_for("book_detail",book_id=book['id'])#(函数名,该函数的参数)
    34. return jsonify(books)
    35. #重定向redirect
    36. @app.route('/profile')
    37. def profile():
    38. #参数传递的两种形式
    39. #1.作为url的组成部分:/book/1
    40. #2.查询字符串:/book?id=1
    41. user_id=request.args.get('id')
    42. if user_id:
    43. return '用户个人中心'
    44. else:
    45. return redirect(url_for("index"),code=302)#暂时性重定向状态码302,永久性重定向301
    46. #渲染
    47. @app.route('/about/')
    48. def about():
    49. context={
    50. 'username':'ZMJ',
    51. 'books':['红楼梦','三国演义','西游记','水浒传'],
    52. 'age':18,
    53. "person":{'name':'zmj','age':18},
    54. }
    55. return render_template("about.html",**context)#html文件默认从templates文件夹下面,**context是解包,传递变量
    56. @app.route('/模板继承/')
    57. def 模板继承():
    58. return render_template('index.html')
    59. @app.route('/index1/')
    60. def index1():
    61. return render_template('index.html')
    62. if __name__ == '__main__':
    63. app.run()

    base.html文件中内容:

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>{% block title %}{% endblock %}title>{#留取空间,且取名为title#}
    6. {% block head%}{% endblock %}
    7. head>
    8. <body>
    9. <ul>
    10. <li>
    11. <a href="/">首页a>
    12. li>
    13. <li>
    14. <a href="/book/list/">图书列表a>
    15. li>
    16. <li>
    17. <a href="/about">关于我a>
    18. li>
    19. ul>
    20. {% block body %}{% endblock %}
    21. <footer style="background-color: #ccc">我是底部的footer>
    22. body>
    23. html>

    forms.py文件中内容:

    1. {% extends 'base.html'%}{#继承模板base.html#}
    2. {% block head %}
    3. 宏模板
    4. {% endblock %}
    5. {% block body %}
    6. <h1>宏模板h1>
    7. {% macro input(name,value='',type='text') %}
    8. <input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
    9. {% endmacro %}
    10. {% macro textarea(name,value='',rows=10,cols=40)%}
    11. <textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols }}">{{ value|e }}textarea>
    12. {% endmacro %}
    13. {% endblock %}

    index.html文件中内容:

    1. {% extends 'base.html' %}{#继承模板base.html#}
    2. {% block title %}
    3. 张梦姣的首页
    4. {% endblock %}
    5. {% block head %}
    6. <link rel="stylesheet" href="{{ url_for('static',filename='CSS/index.css') }}">{#加载静态文件#}
    7. {% endblock %}
    8. {% block body %}
    9. <h1>我是首页h1>
    10. {% endblock %}

    about.html文件中内容:

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>关于我们title>
    6. head>
    7. <body>
    8. <h1>我是{{ username }},长度为{{ username | length}}!!!h1>{#过滤器|#}
    9. <h2>{{ books|join('***') }}h2>
    10. {% if age>18 %}
    11. <div>您已成年div>
    12. {% elif age==18 %}
    13. <div>刚好成年div>
    14. {% else %}
    15. <div>未成年div>
    16. {% endif %}
    17. <ul>
    18. {% for book in books %}
    19. <li>{{ book }}li>{#变量就用两个大括号#}
    20. {% endfor %}
    21. ul>
    22. {% for k,v in person.items() %}
    23. <ul>{{ k }}:{{ v }}ul>
    24. {% endfor %}
    25. {#测试器#}
    26. {% if 'AsC' is upper %}{#'aBcD'是否全部是大写#}
    27. <div>hahahhadiv>
    28. {% else %}
    29. <div>heiheiheidiv>
    30. {% endif %}
    31. {#宏macro:可以传递参数,但是不能有返回值#}{#
    32. {% macro input(name,value='',type='text') %}
    33. {{ name }}<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">
    34. {% endmacro %}
    35. <p>{{ input('李玟琪') }}p>
    36. <p>{{ input('张梦姣',type="password") }}p>#}
    37. {#宏可以直接从自己写的文件"forms.html"中导入#}{#
    38. {% import 'forms.html' as forms %}
    39. <dl>
    40. <dt>Usernamedt>
    41. <dd>{{ forms.input('username') }}dd>
    42. <dt>Passworddt>
    43. <dd>{{ forms.input('password',type='password') }}dd>
    44. dl>
    45. <p>{{ forms.textarea('comment') }}p>#}
    46. {#赋值语句:set,可以赋值为任意类型#}
    47. {% set zzu='郑州大学'%}
    48. <div>我的学校是{{ zzu }}div>
    49. {#限制作用域with:将set语句放在其中,这样创建的变量只在with代码块中才有效#}
    50. {% with %}
    51. {% set a=[('index.html', 'Index'), ('about.html', 'About')] %}
    52. {{ a }}
    53. {% endwith %}
    54. {#也可以在with的后面直接添加变量#}
    55. {% with b='zmj' %}
    56. <li>bli>
    57. {% endwith %}
    58. {#自动转义逃脱#}
    59. {% autoescape false %}{#关闭了自动转义#}
    60. <p>autoescaping is disabled herep>
    61. <p>{{ will_not_be_escaped }}p>
    62. {% endautoescape %}
    63. {#运算符:拼接多个字符串用波浪号~#}
    64. <li>{{ "我爱你," ~ "我也爱你"}}li>
    65. <li>{{ "我爱你," + "我也爱你"}}li>{#不建议#}
    66. {#静态文件的加载:url_for('static',filename='xxx.css')#}
    67. body>
    68. html>

    index.css文件中内容:

    1. h1{
    2. background-color: bisque;
    3. }

    第二章:蓝图

    目录结构如下:

    book.py文件中内容:

    1. """和图书有关的都写在book.py文件中"""
    2. from flask import Blueprint#蓝图
    3. from flask import render_template
    4. #url_prefix:127.0.0.1:5000/book
    5. bp=Blueprint('book',__name__,url_prefix="/book")
    6. @bp.route('/list/')
    7. def book_list():
    8. return render_template('book_list.html')#渲染还是从templates文件夹中寻找

    course.py文件中内容:

    1. """和课程相关的都写在course.py文件中"""
    2. from flask import Blueprint
    3. bp=Blueprint('course',__name__,url_prefix='/course')
    4. @bp.route('/list/')
    5. def course_list():
    6. return "课程列表"

    user.py文件中内容:

    1. """和用户相关的都放在user.py文件中"""
    2. from flask import Blueprint
    3. bp=Blueprint('user',__name__,url_prefix='/user')
    4. @bp.route('/list/')
    5. def user_list():
    6. return "用户列表"

    book_list.html文件中内容:

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>图书列表title>
    6. head>
    7. <body>
    8. <h1>图书列表h1>
    9. <li>《水浒传》li>
    10. <li>《三国演义》li>
    11. <li>《西游记》li>
    12. <li>《红楼梦》li>
    13. body>
    14. html>

    app.py文件中内容:

    1. from flask import Flask
    2. from apps.book import bp as book_bp
    3. from apps.course import bp as course_bp
    4. from apps.user import bp as user_bp
    5. app = Flask(__name__)
    6. #绑定蓝图
    7. app.register_blueprint(book_bp)
    8. app.register_blueprint(course_bp)
    9. app.register_blueprint(user_bp)
    10. @app.route('/')
    11. def hello_world():
    12. return 'Hello World!'
    13. if __name__ == '__main__':
    14. app.run()

    第三章:SQLAlchemy

    1. from flask import Flask
    2. from flask_sqlalchemy import SQLAlchemy
    3. from sqlalchemy import create_engine
    4. app = Flask(__name__)
    5. #数据库的配置变量
    6. HOSTNAME='127.0.0.1'
    7. PORT =3306
    8. DATABASE='zl_flask'
    9. USERNAME='root'
    10. PASSWORD='abc123'
    11. DB_URI='mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
    12. app.config['SQLALCHEMY_DATABASE_URI']=DB_URI
    13. app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True#跟踪修改
    14. db = SQLAlchemy(app)
    15. class User(db.Model):
    16. __tablename__='user'
    17. id=db.Column(db.Integer,primary_key=True,autoincrement=True)
    18. username=db.Column(db.String(200),nullable=False)
    19. class UserExtension(db.Model):
    20. __tablename__='user_extension'
    21. id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    22. school=db.Column(db.String(100))
    23. user_id=db.Column(db.Integer,db.ForeignKey('user.id'))
    24. #db.backref
    25. #1.作用:在反向传播的时候,如果需要传递一些其他的参数,那么就需要用到这个参数;否则不需要使用,只要在relationship的backref参数上设置反向名称就可以了
    26. #2.uselist=False:代表反向引用时,不是一个列表,而是一个对象
    27. user=db.relationship("User",backref=db.backref('extension',uselist=False))
    28. #定义ORM模型
    29. class Article(db.Model):
    30. __tablename__='article'
    31. id=db.Column(db.Integer,primary_key=True,auto_increment=True)
    32. title=db.Column(db.String(200),nullable=False)
    33. content=db.Column(db.Text,nullable=False)
    34. author_id=db.Column(db.Integer,db.ForeignKey("user.id"))#外键:是属于数据库层面的,不推荐使用
    35. #relationship:
    36. #1.第一个参数是模型的名字,必须要和模型名字保持一致
    37. #2.第二个参数代表反向引用,代表对方访问我的时候的字段名称
    38. #3.前提是已经绑定了外键
    39. author=db.relationship("User",backref='articles')#一对多的关系,一个作者可以写很多文章,所以article+s
    40. #暂时还没有涉及到ORM迁移数据库的版本管理,所以现在只能先删除所有表,再创建
    41. db.drop_all()
    42. db.create_all()
    43. @app.route('/otm')#one to many一对多
    44. def one_to_many():
    45. article1=Article(title='111',content='xxx')
    46. article2=Article(title='222',content='yyy')
    47. user=User(username='张梦姣')
    48. article1.author=user
    49. article2.author=user
    50. db.session.add(article1)
    51. db.session.add(article2)
    52. db.session.commit()
    53. return'one to many数据操作成功'
    54. @app.route('/oto')#one_to_one一对一
    55. def one_to_one():
    56. user=User(username='李玟琪')
    57. extension=UserExtension(school='清华大学')
    58. user.extension=extension
    59. db.session.add(user)
    60. db.session.commit()
    61. @app.route('/')
    62. def hello_world():
    63. #写一个测试代码来验证数据库是否连接成功
    64. engine=db.get_engine()
    65. conn=engine.connect()
    66. result=conn.execute('select 1')
    67. print(result.fetchone())
    68. conn.close()
    69. return 'Hello World! ZMJ'
    70. @app.route('/article')
    71. def article_view():
    72. #1.添加数据
    73. article=Article(title='钢铁是怎样炼成的',content='xxx')
    74. db.session.add(article)
    75. #提交
    76. db.session.commit()
    77. #2.查询数据
    78. #filter_by:返回一个类列表的的对象
    79. article =Article.query.filter_by(id=1)[0]
    80. print(article.title)
    81. #3.修改数据
    82. article.content='yyy'
    83. db.session.commit()
    84. #4.删除数据
    85. Article.query.filter_by(id=1)[0].delete()
    86. db.session.commit()
    87. return '数据操作成功'
    88. if __name__ == '__main__':
    89. app.run()

  • 相关阅读:
    第四章 文件管理 四、文件的物理结构(文件分配方式)
    基层医院信息管理系统源码 his系统全套成品源码带电子病历4级
    指针进阶(三)之指针与数组笔试题
    「运维有小邓」AD域委派
    鲸选小试界,存量时代的新「金矿」
    Android 内置webview避免外部跳转或内嵌chrome植入复杂vue项目
    神经网络模型的基本原理,神经网络模型结构图
    LeetCode算法练习top100:(4)链表
    【单元测试】Junit 4(三)--Junit4断言
    ESP8266远程控制电子门
  • 原文地址:https://blog.csdn.net/m0_58086930/article/details/127224062