day94:flask:Jinjia2模板引擎&flask中的CSRF攻击&Flask-SQLAlchemy的创建模型类和基本的增删改查

时间:2022-03-02 00:56:42

目录

1.Jinjia2模板引擎

  1.Jinjia2加载模板并传递数据到模板中

  2.Jinjia2的模板语句

  3.模板中特有的变量和函数

  4.模板中内置的过滤器

  5.自定义过滤器

  6.模板继承

2.在flask中解决CSRF攻击

3.Flask-SQLAlchemy

  1.Flask-SQLAlchemy简单介绍

  2.安装

  3.数据库连接设置

  4.创建模型类

  5.数据基本操作:增删改查

1.Jinjia2模板引擎

1.Jinjia2加载模板并传递数据到模板中

1.设置template_folder参数

2.设置data:

data["num"] = 100

3.传递data到模板:

return render_template( "index1.html", **data )
from flask import Flask,render_template

# 设置template_folder参数,创建template目录
app = Flask(__name__,template_folder="templates") @app.route("/")
def index():
data = {}
data["title"] = "我的第一个flask网页"
data["num"] = 100
# - render_template 函数的第一个参数是模板的文件名,后面的参数都是键值对,表示模板中变量对应的真实值。
return render_template( "index1.html", **data ) if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{title}}</h1>
<p>num={{num}}</p>
</body>
</html>

2.Jinjia2的模板语句

from flask import Flask,render_template

app = Flask(__name__,template_folder="templates")

@app.route("/")
def index():
data = {} # 1.字典
data["info"] = {
"name":"xiaoming",
"age":19,
"sex":True,
"class": "1009"
} # 2.列表
data["student_list"] = ["xiaoming","xiaobai","xiaohei","xiaoan"] # 3.列表内嵌套字典
data["goods_list"] = [
{"id":10,"name":"Python7天入门到放弃","price":99.9,"num":100},
{"id":11,"name":"Python3天入门到放弃","price":99.9,"num":100},
{"id":12,"name":"Python5天入门到放弃","price":99.9,"num":100},
{"id":13,"name":"Go7天入门到放弃","price":99.9,"num":100},
{"id":14,"name":"Go5天入门到放弃","price":99.9,"num":100},
{"id":15,"name":"Linux7天入门到放弃","price":99.9,"num":100},
] return render_template( "index2.html", **data ) if __name__ == '__main__':
app.run(debug=True)

1.访问字典数据中的成员

访问字典数据中的成员,可以通过中括号取值或者点[.]取值

    <p>访问字典数据中的成员</p>
<p>{{ info["name"] }}</p>
<p>{{ info.name }}</p>

2.访问列表数据中的成员

访问列表数据中的成员,可以通过中括号索引取值或者点[.]取值

但是要注意:点[.]语法不支持负数下标

    <p>{{ student_list.0 }}</p>
<p>{{ student_list.2 }}</p>
<p>{{ student_list[-1] }}</p>
<p>{{ student_list[2] }}</p>

3.模板中的if循环

 <p>if判断</p>

<!-- 1.只有if循环 -->
{% if info.age < 18 %}
<p>小明请出去</p>
{% endif %}


<!-- 2.if+else -->
{% if info.age > 10 %}
<p>小明同学</p>
{% else %}
<p>小明小朋友</p>
{% endif %}


<!-- 3.if+elif+else -->
{% if info.age < 10 %}
<p>小明小朋友</p>
{% elif info.age < 18 %}
<p>小明同学</p>
{% else %}
<p>大明同学</p>
{% endif %}

4.模板中的for循环

<p>for循环</p>
<!-- 1.for+if/else -->
<ul>
{% for student in student_list %}
{% if loop.last %}
<li style="background-color:#000;color:#fff;">{{ student }}</li>
{% else %}
<li>{{ student }}</li>
{% endif %}
{% endfor %}
</ul>

5.for循环中的loop用法

loop 是jinja模板引擎提供给开发者获取循环中的信息对象

loop.index 显示本次循环的次数,从1开始 
loop.index0 显示本次循环的次数,从0开始 
loop.first 显示本次是否属于循环的第一次,是则为真

  <!-- 2.for循环中loop的用法 -->
{% for goods in goods_list %}
{% if loop.index % 2 %}
<tr bgcolor="#00bfff">
{% else %}
<tr>
{% endif %}
<td>{{ loop.index0 }}</td>
<td>{{ goods.id }}</td>
<td>{{ goods.name }}</td>
<td>{{ goods.price }}</td>
<td>{{ goods.num }}</td>
</tr>
{% endfor %}

3.模板中特有的变量和函数

模板中特有的变量和函数:config,request,g变量,session,url_for()

from flask import Flask,render_template,session

app = Flask(__name__,template_folder="templates")

app.config["SECRET_KEY"] = "1234asda"

@app.route("/")
def index():
data = {}
session["name"]="xiaohuihui" # 设置内置变量
return render_template( "index3.html", **data ) if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 获取上下文对象 -->
<p>{{ request.url }}</p> <!-- 获取当前请求url -->
<p>{{ request.method }}</p> <!-- 获取当前请求方法 --> <p>{{ session }}</p> <!-- 获取session对象 -->
<p>{{ session.name }}</p> <!-- 获取session指定键对应的值 --> <p>{{ config.DEBUG }}</p> <!-- 获取flask配置的debug的值 --> <p>{{ url_for("index") }}</p> <!-- 获取url中后面的参数 --> </body>
</html>

4.模板中内置的过滤器

from flask import Flask,render_template,session

app = Flask(__name__,  # 当前flask应用运行的模块
static_folder="static", # 当前flask应用保存静态资源[css/js/img/音视频]
static_url_path="/lib", # 当前flask应用提供给外界访问的路径前缀,必须以/开头
template_folder="templates"
) app.config["SECRET_KEY"] = "1234asda" @app.route("/")
def index():
data = {}
data["message"] = "hello,python, after 7 day, byebye"
data["images"] = "<img src='/lib/images/1.jpg'>"
return render_template( "index4.html", **data ) if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
img{
width: 100px;
}
</style>
</head>
<body>
<p>{{ message | upper }}</p> <!-- 变为大写 -->
<p>{{ images | safe }}</p> <!-- 禁用转义 -->
<p>{{ message | reverse | upper }}</p> <!-- 链式调用过滤器 -->
<p>{{ '<em>hello</em>' | striptags }}</p>
<p>{{ "如果x<y,z>x,那么x和z之间是否相等?" | striptags }}</p> <!-- 渲染之前把所有的html标签都删除掉 -->
<p>{{ '床前明月光,疑是地上霜。' | truncate(5,False,'...', 0)}}</p> <!-- 字符串截断 --> <p>{{ [1,1,2,3,4,5,1,2,2,3,4] | unique | list }}</p> <!-- 列表去重 -->
</body>
</html>

5.自定义过滤器

from flask import Flask,render_template

app = Flask(__name__,  # 当前flask应用运行的模块
static_folder="static", # 当前flask应用保存静态资源[css/js/img/音视频]
static_url_path="/lib", # 当前flask应用提供给外界访问的路径前缀,必须以/开头
template_folder="templates"
) app.config["SECRET_KEY"] = "1234asda" # 1.自定义过滤器函数
def do_mobile(content):
return content[:3]+"*****"+content[-3:] # 2.将过滤器函数添加到template_filter中
app.add_template_filter(do_mobile,"mobile") @app.route("/")
def index():
data = {}
data["mobile_list"] = [
"13513241123",
"13513241123",
"13513241123",
"13513241123",
"13513241123",
]
return render_template( "index5.html", **data ) if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for mobile in mobile_list %}
<p>{{ mobile | mobile }}</p> <!-- 使用自定义过滤器 -->
{% endfor %}
</body>
</html>

6.模板继承

from flask import Flask,render_template

app = Flask(__name__,  # 当前flask应用运行的模块
template_folder="templates"
) @app.route("/")
def index():
data = {}
return render_template( "index6.html", **data ) if __name__ == '__main__':
app.run(debug=True)

base.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %} 父级模板的内容 {% endblock %}</title>
{% block hander %} {% endblock hander %}
</head>
<body>
{% block content %}
<p>父级模板的content</p>
{% endblock content %}
</body>
</html>

index6.html

{% extends "base.html" %}

{% block title %}来自子模板的标题{% endblock title %}

{% block hander %}
<script>
alert(1)
</script>
{% endblock hander %} {% block content %}
{{ super() }}
<p>子模板的内容</p>
{{ super() }}
{% endblock %}

2.在flask中解决CSRF攻击

1.安装

pip3 install flask_wtf

2.flask-wtf使用步骤

1.设置应用程序的 secret_key,用于加密生成的 csrf_token 的值

# 1. session加密的时候已经配置过了.如果没有在配置项中设置,则如下:
app.secret_key = "#此处可以写随机字符串#" # 2. 也可以写在配置类中。
class Config(object):
DEBUG = True
SECRET_KEY = "dsad32DASSLD*13%^32" """加载配置"""
app.config.from_object(Config)

2.导入 flask_wtf.csrf 中的 CSRFProtect 类,进行初始化,并在初始化的时候关联 app

from flask.ext.wtf import CSRFProtect
csrf = CSRFProtect(app)

3.在表单中使用 CSRF 令牌

<form method="post" action="/">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>

3.使用CSRF完成简单的登录

from flask import Flask,render_template,request
from flask_wtf import CSRFProtect
app = Flask(__name__, # 当前flask应用运行的模块
template_folder="templates"
) csrf = CSRFProtect(app) app.config["SECRET_KEY"] = "1234asda" @app.route("/")
def index():
data = {}
return render_template( "index7.html", **data ) @app.route("/login",methods=["POST"])
def login():
print(request.form)
return "ok" if __name__ == '__main__':
app.run(debug=True)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="{{ url_for('login') }}" method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" >
账号: <input type="text" name="username" value=""><br><br>
密码: <input type="password" name="password" value=""><br><br>
<input type="submit" value="登录">
</form>
</body>
</html>

3.Flask-SQLAlchemy

1.Flask-SQLAlchemy简单介绍

flask默认提供模型操作,但是并没有提供ORM,所以一般开发的时候我们会采用flask-SQLAlchemy模块来实现ORM操作。

SQLAlchemy是一个关系型数据库框架,它提供了高层的 ORM 和底层的原生数据库的操作。flask-sqlalchemy 是一个简化了 SQLAlchemy 操作的flask扩展。

SQLAlchemy: https://www.sqlalchemy.org/

中文文档: https://www.osgeo.cn/sqlalchemy/index.html

2.安装

1.安装 flask-sqlalchemy【清华源】

pip install flask-sqlalchemy -i https://pypi.tuna.tsinghua.edu.cn/simple

2.如果连接的是 mysql 数据库,需要安装 mysqldb 驱动

pip install flask-mysqldb -i https://pypi.tuna.tsinghua.edu.cn/simple

3.安装flask-mysqldb时,注意

# 安装 flask-mysqldb的时候,python底层依赖于一个底层的模块 mysql-client模块
# 如果没有这个模块,则会报错如下: Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-21hysnd4/mysqlclient/

解决方案:

sudo apt-get install libmysqlclient-dev python3-dev

# 运行上面的安装命令如果再次报错如下:
dpkg 被中断,您必须手工运行 ‘sudo dpkg --configure -a’ 解决此问题。 # 则根据提示执行命令以下命令,再次安装mysqlclient
sudo dpkg --configure -a
apt-get install libmysqlclient-dev python3-dev # 解决了mysqlclient问题以后,重新安装 flask-mysqldb即可。
pip install flask-mysqldb -i https://pypi.tuna.tsinghua.edu.cn/simple

3.数据库连接设置

from flask import Flask,render_template,request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) class Config():
DEBUG = True

# 数据库链接配置
# SQLALCHEMY_DATABASE_URI = "mysql://账号:密码@IP/数据库名?编码"
SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/students?charset=utf8mb4"

# 动态追踪修改设置,如未设置只会提示警告
SQLALCHEMY_TRACK_MODIFICATIONS = True

# 查询时会显示原始SQL语句
SQLALCHEMY_ECHO = True app.config.from_object(Config) db = SQLAlchemy() # 初始化数据库操作对象
db.init_app(app) # 初始化数据库连接

4.创建模型类

from flask import Flask,render_template,request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) class Config():
...... app.config.from_object(Config) db = SQLAlchemy() # 初始化数据库操作对象
db.init_app(app) # 初始化数据库连接


"""创建模型类"""
class Student(db.Model):
__tablename__ = "tb_student"
id = db.Column(db.Integer, primary_key=True,comment="主键ID")
name = db.Column(db.String(250), comment="姓名")
age = db.Column(db.Integer, comment="年龄")
sex = db.Column(db.Boolean, default=False, comment="性别")
money = db.Column(db.DECIMAL(8,2), nullable=True, comment="钱包") def __repr__(self):
return self.name class Teacher(db.Model):
__tablename__ = "tb_teacher"
id = db.Column(db.Integer, primary_key=True, comment="主键ID")
name = db.Column(db.String(250), comment="姓名")
sex = db.Column(db.Boolean, default=False, comment="性别")
option = db.Column(db.Enum("讲师","助教","班主任"), default="讲师", comment="教职") def __repr__(self):
return self.name class Course(db.Model):
__tablename__ = "tb_course"
id = db.Column(db.Integer, primary_key=True, comment="主键ID")
name = db.Column(db.String(250), unique=True, comment="课程名称")
price = db.Column(db.Numeric(6, 2)) def __repr__(self):
return self.name @app.route("/")
def index():
return "Ok" if __name__ == '__main__':
with app.app_context():
db.create_all() # 根据模型创建所有的数据表
db.drop_all() # 删除模型对应的所有数据表
app.run()

5.数据基本操作:增删改查

1.添加一条数据

1.模型类实例对象

2.add

3.commit

student1 = Student(name="小明", sex=True, age=17, email="123456@qq.com", money=100)
db.session.add(student1)
db.session.commit() # 再次插入一条数据
student2 = Student(name='小红', sex=False, age=13, email="16565666@qq.com", money=600)
db.session.add(student2)
db.session.commit()

2.添加多条数据

用add_all+commit

st1 = Student(name='wang',email='wang@163.com',age=22)
st2 = Student(name='zhang',email='zhang@189.com',age=22)
st3 = Student(name='chen',email='chen@126.com',age=22)
st4 = Student(name='zhou',email='zhou@163.com',age=22)
st5 = Student(name='tang',email='tang@163.com',age=22)
st6 = Student(name='wu',email='wu@gmail.com',age=22)
st7 = Student(name='qian',email='qian@gmail.com',age=22)
st8 = Student(name='liu',email='liu@163.com',age=22)
st9 = Student(name='li',email='li@163.com',age=22)
st10 = Student(name='sun',email='sun@163.com',age=22)
db.session.add_all([st1,st2,st3,st4,st5,st6,st7,st8,st9,st10])
db.session.commit()

3.删除数据

1.query+delete+commit

2.query.filter.delete()+commit

# 方法1
student = Student.query.first()
db.session.delete(student)
db.session.commit() # 方法2【事务中使用,就是乐观锁】
ret = Student.query.filter(Student.name=='sun').delete()
db.session.commit()

4.更新数据

# 方法1
student = Student.query.first()
student.name = 'dong' # 直接通过对象.属性 来修改值
db.session.commit() # 方法2【事务中使用,就是乐观锁】
ret = Student.query.filter(Student.name == 'liu').update({'money': 1000})
db.session.commit() # 方法3【批量操作, 实现类似django里面F函数的效果】
ret = Student.query.filter(Student.age == 22).update({Student.money: Student.money+'200'})
db.session.commit()

day94:flask:Jinjia2模板引擎&flask中的CSRF攻击&Flask-SQLAlchemy的创建模型类和基本的增删改查的更多相关文章

  1. Flask项目实战:创建电影网站&lpar;3&rpar;后台的增删改查

    添加预告 根据需求数据库创建表格 需求数据库,关键字title logo # 上映预告 class Preview(db.Model): __tablename__ = "preview&q ...

  2. 在node&period;js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

    Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...

  3. &lbrack;转&rsqb;在node&period;js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

    本文转自:https://www.cnblogs.com/kongxianghai/p/5582661.html Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用Ja ...

  4. Sql中常用的创建表 约束 主外键 增删改查的语句

    创建数据库 USE master; GO --日记数据库 create database DiaryBase on ( name=DiaryBase_Dat,--逻辑名称 FILENAME='c:\D ...

  5. JDBC中 mysql数据库的连接工具类 Java登录 及增删改查 整理 附带:Navicat Premium 11&period;0&period;12中文破解版&period;zip(下载)mysql数据库工具

    先写一个工具类,有实现MySQL数据库连接的方法,和关闭数据库连接.关闭ResultSet  结果集.关闭PreparedStatement 的方法.代码如下: package com.swift; ...

  6. AngularJS中使用&dollar;http对MongoLab数据表进行增删改查

    本篇体验使用AngularJS中的$http对MongoLab数据表进行增删改查. 主页面: <button ng-click="loadCourse()">Load ...

  7. 在ASP&period;NET MVC4中实现同页面增删改查&comma;无弹出框02&comma;增删改查界面设计

    在上一篇"在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建"中,已经搭建好了Repository层,本篇就剩下增删改查的界面了......今 ...

  8. 48&period;Python中ORM模型实现mysql数据库基本的增删改查操作

    首先需要配置settings.py文件中的DATABASES与数据库的连接信息, DATABASES = { 'default': { 'ENGINE': 'django.db.backends.my ...

  9. Laravel 模板引擎Blade中标签详细介绍

    这篇文章主要介绍了Laravel模板引擎Blade中section的一些标签的区别介绍,需要的朋友可以来看看. Laravel 框架中的Blade模板引擎很好用,但是官方文档介绍的并不详细,我接下来将 ...

随机推荐

  1. 将数据导入带模板EXCEL

    在EXCEL模板里设置好样式和格式 点击事件 private void btnReport_Click(object sender, EventArgs e)        {            ...

  2. node相关的精典材料

    node.js电子书 了不起的Node.js 深入浅出Node.js node.js入门经典 node.js开发指南 node.js相关优秀博文 官网 Infoq深入浅出Node.js系列(进阶必读) ...

  3. maya绝招(21--40)

    第21招 将Outliner分成两个 在该视图中如果元素很多的时候,会觉得Outliner不够用,这个时候拖动下侧的底框,就可以分成两栏,这样选择就省事多了. 第22招 运用选择区域,快速选择物体 在 ...

  4. 不能使用ASP&period;NET验证控件---WebForms UnobtrusiveValidationMode 需要&OpenCurlyDoubleQuote;jquery”ScriptResourceMapping。请添加一个名为 jquery &lpar;区分大小写&rpar;的 ScriptRes

    方法一: 在webconfig中找到 <appSettings>        <add key=" aspnet:UseTaskFriendlySynchronizati ...

  5. vue&period;js之动画篇

    本文引入类库的方式均采用CND的方式,可直接复制代码到编辑器中学习和测试 不使用动画切换元素 <div id="app"> <input type="b ...

  6. 转载 CSDN 谈谈我对证券公司一些部门的理解&lpar;前、中、后台&rpar;

    谈谈我对证券公司一些部门的理解(前.中.后台) 2018年02月08日 15:11:07 unirong 阅读数:2165   文中对各大部门的分析都是从作者多年经历总结出来的有感之谈,尤其是前台的6 ...

  7. idea添加JPA导出实体类

    https://blog.csdn.net/liu_yulong/article/details/72910588

  8. Request、Response

    Request Request对象在我们写爬虫发送请求的时候调用,参数如下: url: 就是需要请求的url callback: 指定该请求返回的Response由那个函数来处理. method: 请 ...

  9. UVA10720 Graph Construction 度序列可图性

    Luogu传送门(UVA常年上不去) 题意:求一个度序列是否可变换为一个简单图.$\text{序列长度} \leq 10000$ 题目看起来很简单,但是还是有一些小细节需要注意首先一个简单的结论:一张 ...

  10. JVM源码分析之栈溢出完全解读

    概述 之所以想写这篇文章,其实是因为最近有不少系统出现了栈溢出导致进程crash的问题,并且很隐蔽,根本原因还得借助coredump才能分析出来,于是想从JVM实现的角度来全面分析下栈溢出的这类问题, ...