Web后端学习笔记Flask(2)模板
模板渲染:
在flask中,视图函数可以直接通过render_template进行模板渲染。在flask中,模板文件是存放在template文件夹中:在调用模板文件的时候,模板文件的路径从template文件夹之后开始写,必须写完整的路径,在渲染模板的时候,默认是从项目的templates文件夹查找模板。
from flask import Flask, render_templateapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def hello_world():return 'Hell Wold!'@app.route('/index/')
def index():return render_template("index/index.html")if __name__ == '__main__':app.run(debug=True) # 开启debug模式
如果不想将模板文件放到template文件夹下,则可以修改Flask默认的模板文件路径,进入Flask的定义文件,可以看到Flask的初始化的默认参数,在初始化Flask的时候修改对应的路径即可:
模板传参及其技巧:
在模板渲染的时候,同时也需要将后台的数据渲染到前台。
后端的代码:
from flask import Flask, render_templateapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def hello_world():return 'Hell Wold!'@app.route('/index/')
def index():return render_template("index/index.html", username="Knight-boy", age=18, country="China") # 传递参数if __name__ == '__main__':app.run(debug=True) # 开启debug模式
前端代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>.container{width: 200px;height: 200px;border: 1px solid blanchedalmond;background: burlywood;}</style>
</head>
<body><div class="container"><h4>用户名: {{ username }}</h4><h4>年龄: {{ age }}</h4><h4>国别: {{ country }}</h4></div>
</body>
</html>
渲染的结果:
如果需要传入的参数较多,可以将参数写入到字典中,在进行传参
后台代码:
from flask import Flask, render_templateapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def hello_world():return 'Hell Wold!'@app.route('/index/')
def index():info = {"username": "knight","age": 33,"country": "China"}return render_template("index/index.html", info=info) # 这里参数名字与变量名相同即可if __name__ == '__main__':app.run(debug=True) # 开启debug模式
前端代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>.container{width: 200px;height: 200px;border: 1px solid blanchedalmond;background: burlywood;}</style>
</head>
<body><div class="container"><h4>用户名: {{ info["username"] }}</h4><h4>年龄: {{ info["age"] }}</h4><h4>国别: {{ info["country"] }}</h4></div>
</body>
</html>
还有一种写法,在前端代码中,如果不需要通过字典名获取变量,可以在后端渲染页面传入参数的时候,将字典转换成关键字参数即可,(这种方法使用较多)
from flask import Flask, render_templateapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def hello_world():return 'Hell Wold!'@app.route('/index/')
def index():info = {"username": "knight-b","age": 20,"country": "China"}return render_template("index/index.html", **info)if __name__ == '__main__':app.run(debug=True) # 开启debug模式
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>.container{width: 200px;height: 200px;border: 1px solid blanchedalmond;background: burlywood;}</style>
</head>
<body><div class="container"><h4>用户名: {{ username }}</h4><h4>年龄: {{ age }}</h4><h4>国别: {{ country }}</h4></div>
</body>
</html>
模板中使用URL_FOR
在模板中也会使用url_for,例如在首页中,一般会有一个跳转按钮,再点击跳转按钮之后,会跳转到登录界面
{{ 适合存放变量 }}
{% 适合执行逻辑代码 %}
代码实现:在html代码中,可以使用url_for获取视图函数对应的url
后端代码:
from flask import Flask, render_templateapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def index():return render_template("HTML/index.html")@app.route('/login/')
def login():return render_template("HTML/login.html")if __name__ == '__main__':app.run(debug=True) # 开启debug模式
首页代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>.container{width: 200px;height: 150px;border: 1px solid blanchedalmond;background: burlywood;}</style>
</head>
<body><div class="container"><a href="{{ url_for("login") }}">登陆</a></div>
</body>
</html>
登录页代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>登陆</title><style>.container{width: 250px;height: 170px;border: 1px solid black;background: aquamarine;margin: 20px auto;}.container .username{display: block;margin: 0 auto;margin-top: 15px;}.container .password{display: block;margin: 0 auto;margin-top: 15px;}.container .sub{display: block;margin: 0 auto;margin-top: 15px;}</style>
</head>
<body><div class="container"><input type="text" placeholder="用户名" class="username"><input type="password" placeholder="密码" class="password"><input type="submit" class="sub"></div>
</body>
</html>
过滤器基本使用:
过滤器是通过管道符号(|)进行使用的,例如{{ name|length }},将返回name的长度。过滤器相当于一个函数,把当前的变量传入到过滤器中,过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面。jingja2中内置了很多的过滤器,常用到的过滤器有:
1. abs(value), -1 | abs
2. first(value): 返回一个序列的第一个值 value | first
3. last(value): 返回最后一个值 value | last
更多的可以参考jingja2的手册:
后端代码:
from flask import Flask, render_templateapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def index():return render_template("HTML/index.html", position=-6)if __name__ == '__main__':app.run(debug=True) # 开启debug模式
前端代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>.container{width: 200px;height: 150px;border: 1px solid blanchedalmond;background: burlywood;}</style>
</head>
<body><div class="container"><span>The position is : {{ position|abs }}</span></div>
</body>
</html>
default过滤器详解:
对于传入的变量,如果有值,就返回变量的值,否则就返回default值,再在过滤器中,设置boolean参数为真,才可以将空字符串,空列表,null,None当作false来处理,否则即使有这些值,也会当作有值来处理。
escape过滤器:
转义字符,会将< >等符号转义成html中的符号。例如: content | escape, jingja2中的转义是默认开启的。
safe过滤器:
关闭字符串的自动转义 ,功能与{%autoescape off%} , {%endautoescape%}的类似
first / last过滤器:
获取序列的第一个或者最后一个元素
format过滤器:
用于格式化输出字符串 {{ “%s -- %s" }} | format(str1, str2)
length过滤器:
获取序列的长度
join过滤器:
将一个序列用特定的符号进行拼接
int, float, string过滤器:(用于模板的条件渲染)
对数值进行转换
lower, upper过滤器:
进行大小写转换
wordcount过滤器:
计算一个字符串中的单词数量
replace过滤器
实现字符串中的替换功能,replace(oldstr, newstr)
truncate过滤器:
截取一定长度的字符串,truncate(value, length, killwords=false), 后面的内容使用...表示,用于当显示内容较多时,显示缩略的内容。
stringtags过滤器:
删除字符串中所有的html标签,如果出现多个空格,将替换成一个空格。
后端代码:
from flask import Flask, render_templateapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def index():info = {"position": -6,"signature": None,"content": '<script>alert("Hell")</script>',"persons": ["tom", "lily", "Cart"],"age": "14","text": "This is aa cc aa"}return render_template("HTML/index.html", **info)if __name__ == '__main__':app.run(debug=True) # 开启debug模式
前端代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>.container{width: 300px;height: 250px;border: 1px solid blanchedalmond;background: burlywood;}.container span{display: block;}</style>
</head>
<body><div class="container"><span>The position is : {{ position|abs }}</span><span>The signature is : {{ signature|default('no signature at all', boolean=True) }}</span><span>The content is: {{ content|escape }}</span><span>The content is: {{ content|safe }}</span> <!--关闭了自动转义,会弹出模态对话框--><span>First person is {{ persons|first }}</span><span>Last person is {{ persons|last }}</span><sapn>format use: {{ "%s -- %s" | format("hello", "cute")}}</sapn><span>Persons number is: {{ persons|length }}</span>{% if age|int >= 18 %} <!--模板的条件选择渲染--><span>The age is ok</span>{% else %}<span>The age is not ok</span>{% endif %}<span>Replace result: {{ text|replace("aa", "***") }}</span><span>Truncated text is: {{ text|truncate(length=5) }}</span></div>
</body>
</html>
自定义过滤器:
在Jingja2内置的过滤器不能满足需求的时候,需要使用自定义的过滤器:
from flask import Flask, render_templateapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件
app.config["TEMPLATES_AUTO_RELOAD"] = True # 保证模板修改后能够自动加载@app.route('/')
def index():info = {"text": "This is aa cc aa"}return render_template("HTML/index.html", **info)@app.template_filter("cut_xx") # 注册过滤器的名称
def cut_xx(string, newstr, oldstr):"""自定义过滤器:param string::param newstr::param oldstr::return:"""value = string.replace(oldstr, newstr)return valueif __name__ == '__main__':app.run(debug=True) # 开启debug模式
自定义时间处理过滤器:
from flask import Flask, render_template
from datetime import datetimeapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件
app.config["TEMPLATES_AUTO_RELOAD"] = True # 保证模板修改后能够自动加载@app.route('/')
def index():info = {"text": "This is aa cc aa","content": None,"create_time": datetime(2020, 4, 5, 2, 12, 22)}return render_template("HTML/index.html", **info)@app.template_filter("cut_xx") # 注册过滤器的名称
def cut_xx(string, newstr, oldstr):"""自定义过滤器:param string::param newstr::param oldstr::return:"""value = string.replace(oldstr, newstr)return value@app.template_filter("handle_time")
def handle_time(time):"""发表时间距离现在时间1. 一分钟以内,显示刚刚2. 一小时以内,显示xx分钟3. 24小时以内,显示xx小时4. 大于二十四小时,显示xx天前:param time::return:"""if isinstance(time, datetime):time_span = datetime.now() - timeseconds = time_span.total_seconds()if seconds < 60:return "刚刚"elif seconds < 60 * 60:return "%d分钟前" % (seconds/60)elif seconds < 24 * 60 * 60:return "%d小时以前" % (seconds/60/60)else:return "%d天以前" % (seconds/24/60/60)else:return timeif __name__ == '__main__':app.run(debug=True) # 开启debug模式
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>.container{width: 300px;height: 250px;border: 1px solid blanchedalmond;background: burlywood;}.container span{display: block;}</style>
</head>
<body><div class="container"><span>The time is: {{ create_time|handle_time }}</span></div>
</body>
</html>
实现效果:
jingja2模板中条件判断,循环:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>.right{color: #7666c1;}.wrong{color: #19a71f;}</style>
</head>
<body>{% if username=="tom" %}<p class="right">hello, this is tom</p>{% else %}<p class="wrong">This is not tom</p>{% endif %}
</body>
</html>
for循环可以遍历任何一个序列,包括列表,字典,元组,并且可以进行反向遍历:
但是jingja模板中,不支持用continue和break来控制循环,且for循环中还提供了以下的变量,用来获取遍历的状态:
loop.index 当前迭代的索引(从1开始)
loop.index0 当前迭代的索引(从0开始)
loop.first 是否是第一次迭代,返回bool值
loop.last 是否是最后一次迭代,返回bool值
loop.length 序列的长度
jingja2中的for循环可以由else,如果序列为空的话,会进入else语句:
后端代码:
from flask import Flask, render_templateapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False) # 加载配置文件config, 也可以加载普通的txt文件
app.config["TEMPLATES_AUTO_RELOAD"] = True # 保证模板修改后能够自动加载@app.route('/')
def index():info = {"username": "kit","persons": ["kit", "hack", "tom", "nancy"],"books": [{"name": "gone with wind","author": "unknown","price": 120,"count": 35},{"name": "Pride and Prejudice","author": "Jane Austing","price": 30,"count": 120},{"name": "Become Jane","author": "Jane Austing","price": 670,"count": 40}]}return render_template("HTML/index.html", **info)if __name__ == '__main__':app.run(debug=True) # 开启debug模式
前端代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>*{margin: 0;padding: 0;}.person{width: 200px;border: 1px solid #fcffe8;margin-bottom: 20px;overflow: hidden;}.person p{font-size: 18px;color: #783476;font-weight: bold;display: block;background: aqua;}.person .info{width: 100%;line-height: 20px;font-size: 16px;color: #123;background: #917e46;}table{border: 1px solid black;text-align: center;}table td, th{border: 1px solid black;}</style>
</head>
<body>{% for person in persons %}<div class="person"><p>Hello, I am {{ person }}</p><div class="info">coco</div></div>{% else %}<div class="person"><p>Hello, no person</p><div class="info">no one is here</div></div>{% endfor %}<table><thead><tr><th>index</th><th>book name</th><th>author</th><th>price</th><th>count</th></tr></thead><tbody>{% for book in books %}{% if loop.first %}<tr style="background: red"> <!--将第一行设置为背景颜色为红色-->{% elif loop.last %}<tr style="background: orange">{% else %}<tr>{% endif %}<td>{{ loop.index }}</td><td>{{ book["name"] }}</td><td>{{ book["author"] }}</td><td>{{ book["price"] }}</td><td>{{ book["count"] }}</td></tr>{% endfor %}</tbody></table></body>
</html>
实际效果:
jinja2中的宏,基本概念及使用:
宏类似于python中的函数,当一段代码需要反复使用的时候,可以将其封装为函数,这样在需要使用的时候就可以进行调用。模板中的宏可以传递参数,但是不能有返回值,可以将经常使用的代码片段放到宏中,然后把一些不固定的值抽取出来当成变量。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style></style>
</head>
<body><!--定义宏-->{% macro input(name, type="text", value="") %}<input type="{{ type }}" name="{{ name }}" value="{{ value }}">{% endmacro %}<!--使用宏--><div class="container"><label><p>用户名</p>{{ input("username") }}</label><label><p>密码</p>{{ input("password", "password") }}</label>{{ input("submit", "submit", "提交") }}</div>
</body>
</html>
宏的导入和注意事项:
通常在开发中,会将宏进行分类,放到单独的文件中,所以在其他的文件中需要调用宏的时候,首先需要将宏导入到文件中,才能够调用。
导入宏的方式和python中导入包非常类似,import xxx, import xxx as yyy, from xxx import yyy
{% from "HTML/login_form.html" import input %}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style></style>
</head>
<body><!--使用宏--><div class="container"><label><p>用户名</p>{{ input("username") }}</label><label><p>密码</p>{{ input("password", "password") }}</label>{{ input("submit", "submit", "提交!") }}</div>
</body>
</html>
宏文件在其他文件夹中的时候,需要以templates文件夹为根目录,开始查找。不能通过相对路径查找。
如果需要在导入宏的时候,将当前一些模板的参数传给宏所在的模板,那么在导入的时候应该使用with context, 例如:
from xxx import yyy with context
include 标签使用:
1. include表示将另一个文件中的代码,复制粘贴到include的当前位置。(有点c++中inline函数的意思)
2. include完全可以直接调用父模板中的变量:
3. 在include文件的路径时,只需要按照templates根目录进行加载,不能使用相对路径。跟import的路径形式一样
例如,分别定义header.html以及footer.html
header.html:(html +css代码)
<style>.nav{width: 100%;height: 40px;overflow: hidden;background: aquamarine;}.nav ul{font-size: 18px;color: black;line-height: 40px;}.nav ul li:hover{background: blue;}.nav ul li{float: left;margin-left: 15px;}
</style><div class="nav"><ul><li>首页</li><li>课程详情</li><li>视屏教程</li><li>关于我们~</li><li>{{ username }}</li></ul>
</div>
footer.html
<style>.footer{width: 100%;height: 200px;background: black;color: white;}
</style><div class="footer">这是底部footer
</div>
例如,需要在index.html中include文件header.html以及footer.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><style>*{margin: 0;padding: 0;}ul{list-style: none;}a{text-decoration: none;}.middle{width: 100%;height: 300px;background: burlywood;}</style>
</head>
<body>{% include "common/header.html" %}<div class="middle">中间部分</div>{% include "common/footer.html" %}
</body>
</html>
此时,如果需要在不同的页面中使用header.html和footer.html.只需要在页面中include这两个文件即可。
set,with语句以及模板中定义常量:
在模板中,应该如何定义常量:{% set username=" xxx" %}
还可以使用with语句定义变量,with语句有起始和结束的地方,所以在with语句块内,可以使用该变量,但是在with语句块以外,不能使用这一变量。
{% with username="hell" %}
可以使用变量username的语句块
{% endwith %}
<body>{% set username="Tom" %} <!--定义常量--><p>用户名:{{ username }}</p>{% with name="hell" %}<p>This is user {{ name }}</p>{% endwith %}
</body>
也可以定义一个空的with语句,在这个空的with语句中,可以使用set定义变量,定义的变量也只能在这个with语句块中使用:
{% with %}
{% set name="xxx" %}
可以使用变量username的语句块
{% endwith %}
jingja2中加载静态文件:
静态文件: css文件,js文件,字体文件,图片文件,在flask中,静态文件存储在static文件夹下,在flask中加载静态文件,文件路径需要使用url_for("static", filename="路径")进行加载,其中路径需要以static文件夹为根目录。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>访问首页</title><link rel="stylesheet" href="{{ url_for('static', filename='css/index.css') }}"><script rel="script" src="{{ url_for('static', filename='JS/index.js') }}"></script></head>
<body><div class="container">加载静态文件</div><div class="picture"><img src="{{ url_for('static', filename='images/sunset.png') }}" alt=""></div>
</body>
</html>
jingja2中模板继承:
1. 为什么需要模板继承:
模板继承可以把一些公用的代码单独抽取出来,放到父模板中,以后子模版直接继承就可以使用了,减少重复性的代码,修改起来也更加的简单。
2. 使用extends来指明继承的父模板,父模板的路径也是相对于templates文件夹下的绝对路径。
3. 在父模板中,只能实现一些公共的代码。这时候父模板应该有能力提供一个接口,让父模板来实现
实例:
父类的html代码:设计整个模板,header, footer是共用的部分
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>{% block title %}{% endblock %}</title><style>.nav{width: 100%;height: 40px;overflow: hidden;background: aquamarine;}.nav ul{font-size: 18px;color: black;line-height: 40px;}.nav ul li:hover{background: blue;}.nav ul li{float: left;margin-left: 15px;}.footer{width: 100%;height: 200px;background: black;color: white;}</style>
</head>
<body><div class="nav"><ul><li>首页</li><li>课程详情</li><li>视屏教程</li><li>关于我们~</li></ul></div>{% block content %}<!--相当于占位的功能,具体的内容在子模板中实现-->{% endblock %}<div class="footer">这是底部footer</div>
</body>
</html>
定义自类的代码,继承父类:
<!--首页实现,继承自模板-->
{% extends "common/base_template.html" %} <!--继承父类-->{% block title %}CMS系统
{% endblock %}{% block content %}<style>*{margin: 0;padding: 0;}ul{list-style: none;}.content-block{width: 100%;height: 200px;background: purple;margin-top: 20px;}.content-block span{font-size: 18px;color: #ab811e;display: block;}.content-block .item{width: 50%;height: 100px;margin-top: 20px;z-index: 2;}</style><div class="content-block"><span>This is content</span><div class="item"></div></div>
{% endblock %}
----------------------------------------------------------------------------------------------------------------------------------------
Web后端学习笔记Flask(2)模板相关推荐
- Web后端学习笔记 Flask(1)基础知识
基础的准备 1. 使用的python版本 python3.6 2. pycharm编辑器 3. 安装python虚拟环境: python中的虚拟环境: python中的虚拟环境相当于一个抽屉,在这个抽 ...
- Web后端学习笔记Flask(3)模板 实例
豆瓣微信小程序: 在代码调试的过程中,一般css文件不生效,可以按照以下的方法检查: 1. 如果遇到修改的CSS文件不能生效,首先需要检查,css文件路径,以及css选择器书写是否正确 2. 设置浏览 ...
- Web后端学习笔记 Flask(10)CSRF攻击原理
CSRF(Cross Site Request Forgery,跨站域请求伪造)是一种网络的攻击方式,它在2007年曾被列为互联网20大安全隐患之一. CSRF攻击的原理: 网站是通过cookie实现 ...
- Web后端学习笔记 Flask(9)cookie and session
Flask_wtf除了可以做表单验证,模板渲染之外,还可以防御CSRF攻击.要了解CSRF攻击的原理,首先需要了解cookie和session的知识点. cookie:在网站中,HTTP请求是无状态的 ...
- Web后端学习笔记 Flask(11)Local线程隔离对象
flask中的上下文:应用上下文和请求上下文 1. 在flask中,是通过request对象获取用户提交的数据,但是在整个程序运行中,只有一个request对象.在实际应用场景中,会有多个用户同时进行 ...
- Web后端学习笔记 Flask(8) WTForms 表单验证,文件上传
Flask-WTF是简化了WTForms操作的一个第三方库.WTForms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板.同时还包含一些其他的功能.例如CSRF保护,文件上传等功能,安装fl ...
- Web后端学习笔记 Flask (5) 数据库
MySql数据库安装:省略 SQLAlchemy介绍和基本使用: 数据库是开发网站的基础,,在Flask中,支持的数据库有:MySql,PostgreSql,SQLite,Redis,MongoDB来 ...
- Web后端学习笔记 Flask(4)视图函数
Flask中的视图函数以及视图类: 添加视图函数还可以通过下面的方式add_url_rule进行: app.add_url_rule(rule, endpoint, view_func): rul ...
- Web后端学习笔记 Flask(7)数据库
高级查询: 1. group_by 根据某个字段进行分组,比如说需要根据某个字段分组,来统计每组有多少人. 2. having having是对查询结果进一步过滤,比如只想看到未成年人的数量,那么首先 ...
最新文章
- python实现快排算法(quicksort)
- acwing 7 混合背包
- exadata磁盘组无法mount恢复---惜分飞
- 详解Objective-C的meta-class
- 面试英语自我介绍的常用词汇
- Delphi下DLL调用以及共享数据库连接
- 使用threeJS根据点的坐标绘制曲线
- apk反编译java_Android的APK文件如何反编译成Java文件
- 爬虫-网易云音乐视频下载链接
- Ubuntu 18.04安装Eclipse教程
- matlab 图像傅里叶逆变换,用MATLAB实现图像的傅里叶变换.ppt
- android qq音乐无法连接网络连接,qq音乐不能播放_qq音乐为什么老是提示说歌曲无效或网络连接失败呢?...
- xxjob分布式定时任务简单入门和改造
- 乱谈计算机、转专业、考研
- android mvp设计思想,android MVP 设计模式
- EN 12101-8:2011烟雾和热量控制系统防烟挡板—CE认证
- Java编程那些事儿78——时间和日期处理
- 误删除与误格式化的挽回(图)
- python 爬取王者荣耀高清壁纸
- 基于RGB颜色空间的算法
热门文章
- STM32工作笔记0091---ADC模数转换实验-M3
- Web前端工作笔记002---$(function(){})和$(document).ready(function(){}) 的区别
- PostGreSql工作笔记003---在Navicat中创建数据库时报错rolcatupdate不存在_具体原因看其他博文_这里使用pgAdmin4创建管理postgre
- 安卓异常总结---GestureBuilder] Re-installation failed due to different application signatures
- python数据结构-图
- java catch用法_java – 如何避免使用try … catch块
- linux基础-文本编辑器,Linux基础之vim文本编辑器
- linux进程阻塞例子,一个Linux守候进程例子
- django jsonresponse_0基础掌握Django框架(29)HttpResponse对象
- Python群机器人发送城市天气情况