flask学习
- django是一个大而全的框架,flask是一个轻量级的框架。
- django内部为我们提供了非常多的组件:orm/session/cookie/admin/form/modelform/路由/视图/模板/中间件/分页/auth组件/contenttype/缓存/信号/多数据库连接。
- flask框架本身没有太多的功能:路由/视图/模板(jinja2)/session/中间件,第三方组件非常齐全。
- 【注意事项】django的请求处理是逐一封装和传递;而flask的请求是利用上下文管理来实现的。
文件目录结构如下:
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/',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//')
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文件中内容:
{% block title %}{% endblock %} {#留取空间,且取名为title#}
{% block head%}{% endblock %}
{% block body %}{% endblock %}
forms.py文件中内容:
{% extends 'base.html'%}{#继承模板base.html#}
{% block head %}
宏模板
{% endblock %}
{% block body %}
宏模板
{% macro input(name,value='',type='text') %}
{% endmacro %}
{% macro textarea(name,value='',rows=10,cols=40)%}
{% endmacro %}
{% endblock %}
index.html文件中内容:
{% extends 'base.html' %}{#继承模板base.html#}
{% block title %}
张梦姣的首页
{% endblock %}
{% block head %}
{#加载静态文件#}
{% endblock %}
{% block body %}
我是首页
{% endblock %}
about.html文件中内容:
关于我们
我是{{ username }},长度为{{ username | length}}!!!
{#过滤器|#}
{{ books|join('***') }}
{% if age>18 %}
您已成年
{% elif age==18 %}
刚好成年
{% else %}
未成年
{% endif %}
{% for book in books %}
- {{ book }}
{#变量就用两个大括号#}
{% endfor %}
{% for k,v in person.items() %}
{{ k }}:{{ v }}
{% endfor %}
{#测试器#}
{% if 'AsC' is upper %}{#'aBcD'是否全部是大写#}
hahahha
{% else %}
heiheihei
{% endif %}
{#宏macro:可以传递参数,但是不能有返回值#}{#
{% macro input(name,value='',type='text') %}
{{ name }}
{% endmacro %}
{{ input('李玟琪') }}
{{ input('张梦姣',type="password") }}
#}
{#宏可以直接从自己写的文件"forms.html"中导入#}{#
{% import 'forms.html' as forms %}
- Username
- {{ forms.input('username') }}
- Password
- {{ forms.input('password',type='password') }}
{{ forms.textarea('comment') }}
#}
{#赋值语句:set,可以赋值为任意类型#}
{% set zzu='郑州大学'%}
我的学校是{{ zzu }}
{#限制作用域with:将set语句放在其中,这样创建的变量只在with代码块中才有效#}
{% with %}
{% set a=[('index.html', 'Index'), ('about.html', 'About')] %}
{{ a }}
{% endwith %}
{#也可以在with的后面直接添加变量#}
{% with b='zmj' %}
b
{% endwith %}
{#自动转义逃脱#}
{% autoescape false %}{#关闭了自动转义#}
autoescaping is disabled here
{{ will_not_be_escaped }}
{% endautoescape %}
{#运算符:拼接多个字符串用波浪号~#}
{{ "我爱你," ~ "我也爱你"}}
{{ "我爱你," + "我也爱你"}} {#不建议#}
{#静态文件的加载:url_for('static',filename='xxx.css')#}
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文件中内容:
图书列表
图书列表
《水浒传》
《三国演义》
《西游记》
《红楼梦》
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()
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()