Pycharm+Flask,具体流程如下,打开Pycharm
记得选下面这个Previously configured interpreter
选项,上面那个是新建环境,而这个是自己C盘的环境,上面那个容易出现报错。
然后接下来可以发现有两个文件夹+一个文件,app.py
是主入口文件,static
是静态文件夹,templates
是模板文件夹
其app.py
内代码具体作用如下(而后点击右上角的小绿三角进行运行)
可以发现下方的URL,访问即可
说一下为什么要配置这个
当我们运行一个程序
此时已经运行起来了,比如我们想更换返回内容为Welcome quan9i's blog
,但我们修改过后打开浏览器会发现是没有变化的,这是因为没有开启debug
模式,这个时候我们如果想在浏览器上看到效果,我们还需要重新关闭再开启,这个相对是比较麻烦的,而当我们开启debug模式后,我们则可以直接修改,而后在浏览器查看变化。
如何开启debug
模式呢,关闭程序运行,而后点击右上角
此时勾选完FLASK_DEBUG
点击Apply
,如何点击ok
即可,此时再来运行
将内容修改为Welcome quan9i
,此时打开浏览器查看
修改这个的作用是为了使其他电脑能访问到自身电脑的FLask项目。
如何配置呢,与刚刚类似,右上角打开编辑
在这里添加一个--host=0.0.0.0
即可
默认为5000端口,当5000端口被占用,想进行更换时,可以和刚刚host相似,在同一处加上--port =8088
,即可配置为8088端口
此时再运行文件
端口从5000变成了8088端口
我们可以自行定义新的路由,比如像这样
@app.route('/quan9i')
def quan9i():
return "我是quan9i"
@app.route('/blog')
def blog():
return "Welcome my blog"
接下来运行访问查看效果
那么我们如何写入有参数的路由呢,这里举个例子,示例如下
@app.route('/blog/<blog_id>') #<blog_id>可以改为<int:blog_id>或<string:blog_id>,这个的话其实就是一个数据强制转换
def blog_detail(blog_id):
return "您访问的是博客的第%s篇文章" % blog_id
接下来尝试去进行访问
但这个相对来说不是很灵活,还有一种方式,是采用request.args
的方法来写一个有参数的路由,具体示例如下
@app.route('/book/list')
def book_list():
#request.args: 类字典类型
page = request.args.get("page",default=1,type=int)#default是默认值,不填参数则默认值为1
return f"您获取的是第{page}页的图书列表
#f是将当前环境中的变量直接放入花括号中进行使用
这个的话需要我们去导入request
模块,然后我们去访问
接下来传值
点击template
中的html
接下来命名为index.html
,随便编写一下内容
那我们这里该如何进行使用呢,这里需要调用一个模块,即render_template
模块,然后简单修改代码即可,具体如下
from flask import Flask,render_template #从Flask包中调用flask
app = Flask(__name__)
#使用Flask类创建一个app对象
#__name__:代表当前app.py这个模块
#作用1:以后出现bug,他可以帮助我们快速定位
#作用2:对于寻找模板文件,有一个绝对路径
#创建一个路由和视图函数的映射
@app.route('/')
#定义跟路由
def hello_world(): # put application's code here
return render_template("index.html")
if __name__ == '__main__': #如果当前文件为主入口,就会往下运行
app.run()
此时运行程序,访问网页
那么如何对有参数的文件进行一个模板渲染呢,与此类似,这里简单说一下,首先在template
文件夹下新建html文件
,然后我们这里假设变量是blog_id
,Jinjia2
模板引用变量的方式是{{变量名}}
,所以我们这里这样写即可
而后我们的主文件app.py
这样写
from flask import Flask,render_template #从Flask包中调用flask
app = Flask(__name__)
#使用Flask类创建一个app对象
#__name__:代表当前app.py这个模块
#作用1:以后出现bug,他可以帮助我们快速定位
#作用2:对于寻找模板文件,有一个绝对路径
#创建一个路由和视图函数的映射
@app.route('/')
#定义跟路由
def hello_world(): # put application's code here
return render_template("index.html")
@app.route('/blog/<blog_id>')
def blog_detail(blog_id):
return render_template("blog_detail.html",blog_id=blog_id)
if __name__ == '__main__': #如果当前文件为主入口,就会往下运行
app.run()
此时去访问界面并附加参数
模板该如何访问对象的属性呢,我们这里以一个例子来进行相关讲解。
主入口文件app.py
具体代码如下
from flask import Flask,render_template #从Flask包中调用flask
app = Flask(__name__)
class User:
def __init__(self,username,email):
self.username = username
self.email = email
@app.route('/')
def hello_world():
user = User(username="quan9i",email="qwq@qq.com")
person = {
"username" : "赵四",
"email":"zhaosi@qq.com"
}
return render_template("index.html",user=user,person=person)
if __name__ == '__main__': #如果当前文件为主入口,就会往下运行
app.run()
可以看到这里是定义了一个User
对象,其中含有username
和email
属性,同时呢,我们这里也采用字典的方式,写入一个person
参数,其中也包含这两个属性,接下来如何访问呢,在Jinjia2
模板中,字典可以通过字典名[属性]
来访问,也可以这样访问字典名.属性
,我们的index.html
文件内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>quan9i's blog</title>
</head>
<body>
<h1>欢迎来到博客首页</h1>
<div>{{ user.username }}/{{ user.email }}</div>
<div>{{ person['username'] }}/{{ person.email }}</div>
</body>
</html>
接下来执行程序,访问界面,可以看到这两个是都可以的。
常见的过滤器如下
abs(value):返回一个数值的绝对值。示例:-1|abs
default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。示例:name|default(‘xiaotuo’)——如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。
escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。显例:content|escape或content|e。
first(value):返回一个序列的第一个元素。示例:names|first
format(value,arags,*kwargs):格式化字符串。比如:{{ "%s" - "%s"|format('Hello?',"Foo!") }}将输出:Helloo? - Foo!
last(value):返回一个序列的最后一个元素。示例:names|last。
length(value):返回一个序列或者字典的长度。示例:names|length。
join(value,d=u”):将一个序列用d这个参数的值拼接成字符串。
safe(value):如果开启了全局转义,那么safe过滤器会将变量关掉转义。示例:content_html|safe。
int(value):将值转换为int类型。
float(value):将值转换为float类型。
lower(value):将字符串转换为小写。
upper(value):将字符串转换为小写。
replace(value,old,new): 替换将old替换为new的字符串。
truncate(value,length=255,killwords=False):截取length长度的字符串。
striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。
trim:截取字符串前面和后面的空白字符。
string(value):将变量转换成字符串。
wordcount(s):计算一个长字符串中单词的个数。
那么如何进行使用呢,具体如下所示,向这些内置的,即Python自带的,我们直接使用管道符|
加上过滤器名
即可使用,我们这里的index.html
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>quan9i's blog</title>
</head>
<body>
<h1>欢迎来到博客首页</h1>
<div>{{ user.username }}————{{ user.username|length }}</div>
</body>
</html>
接下来访问界面
可以看到返回了6,对应的是quan9i
的长度,接下来说一下如何自定义过滤器。其实自定义一个函数,如何再简单设置一下即可,具体app.py
代码如下
from flask import Flask,render_template #从Flask包中调用flask
from datetime import datetime
app = Flask(__name__)
def datetime_format(value,format="%Y年-%m月-%d日 %H:%H"):
return value.strftime(format)
app.add_template_filter(datetime_format,"dformat")#增添一个自定义函数作为过滤器,并命名为dformat
class User:
def __init__(self,username,email):
self.username = username
self.email = email
@app.route('/')
def hello_world():
user = User(username="quan9i",email="qwq@qq.com")
mytime = datetime.now()
return render_template("index.html",user=user,mytime=mytime)
if __name__ == '__main__': #如果当前文件为主入口,就会往下运行
app.run()
此时再设置一下index.html
,具体内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>quan9i's blog</title>
</head>
<body>
<h1>欢迎来到博客首页</h1>
<div>{{ user.username }}————{{ user.username|length }}</div>
<div>{{ mytime|dformat }}</div>
</body>
</html>
此时访问界面
可以发现自定义过滤器已生效,格式就是我们刚刚设置的那种,年月日的形式。
控制语句,常见的是if
和for
,而在Jinja2
中,写语句的话需要注意格式是{% xx %}
,同时需要写上end
进行闭合,比如if`语句就是
{% if xxx %}
....
{% endif %}
对for
语句就是
{% for xxx in xxx %}
...
{% endfor %}
接下来举个例子,我们这里的入口文件app.py
内容如下
from flask import Flask,render_template #从Flask包中调用flask
app = Flask(__name__)
class User:
def __init__(self,username,email):
self.username = username
self.email = email
@app.route('/')
def hello_world():
age = 17
books = [{
"name":"三国演义",
"author":"罗贯中"
},{
"name":"水浒传",
"author":"施耐庵"
}]
return render_template("control.html",age=age,books=books)
if __name__ == '__main__': #如果当前文件为主入口,就会往下运行
app.run()
我们的control.html
内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>控制语句demo</title>
</head>
<body>
{% if age>18 %}
<div>您已经满18岁,可以进入网吧</div>
{% elif age==18 %}
<div>您刚满18岁,需要父母陪同进入网吧</div>
{% else %}
<div>您未满18岁,不能进入网吧</div>
{% endif %}
{% for book in books %}
<div>图书名称:{{ book.name }},图书作者:{{ book.author }}</div>
{% endfor %}
</body>
</html>
此时访问界面
一些模块,比如导航栏和底部信息是常用的,如果每次都去写,是比较麻烦的。
对于这个的实现,我们这里以代码为例,主入口文件app.py
内容如下
from flask import Flask,render_template #从Flask包中调用flask
app = Flask(__name__)
@app.route('/')
def hello_world():
age = 17
books = [{
"name":"三国演义",
"author":"罗贯中"
},{
"name":"水浒传",
"author":"施耐庵"
}]
return render_template("control.html",age=age,books=books)
@app.route('/child')
def child():
return render_template("child.html")
if __name__ == '__main__': #如果当前文件为主入口,就会往下运行
app.run()
我们的父模板base.html
内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父模板</title>
</head>
<body>
<h1>我是父模板的文字</h1>
</body>
</html>
我们的子模板child.html
内容如下
<% extends "base.html"%>
而后可以看到我们主入口文件中是用的child.html
,接下来去访问界面
此时发现是复刻了父模板,但实际情况不可能要求一模一样,我们如何进行更改呢,这里仍然以代码为例
主文件入口app.py
内容如下
from flask import Flask,render_template #从Flask包中调用flask
app = Flask(__name__)
@app.route('/')
def hello_world():
age = 17
books = [{
"name":"三国演义",
"author":"罗贯中"
},{
"name":"水浒传",
"author":"施耐庵"
}]
return render_template("control.html",age=age,books=books)
@app.route('/child')
def child():
return render_template("child.html")
@app.route('/child2')
def child2():
return render_template("child2.html")
if __name__ == '__main__': #如果当前文件为主入口,就会往下运行
app.run()
父模板base.html
内容为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">新闻</a></li>
</ul>
{% block name %}
{% endblock %}
<footer>这是底部的标签</footer>
</body>
</html>
子模板1child.html
内容为
{% extends "base.html" %}
{% block title %}
我是子模板的标题
{% endblock %}
{% block name %}
我是子模板的name
{% endblock %}
子模板2child2.html
内容为
{% extends "base.html" %}
{% block title %}
我是child2
{% endblock %}
{% block name %}
我是child2
{% endblock %}
此时分别访问child
和child2
可以发现两个只有中间不同,头部和底部都是相同的
除了放html文件,我们还需要放一些图片,js,css文件
接下来首先说一下加载图片,主文件app.py
内容如下
from flask import Flask,render_template #从Flask包中调用flask
app = Flask(__name__)
@app.route('/')
def hello_world():
age = 17
books = [{
"name":"三国演义",
"author":"罗贯中"
},{
"name":"水浒传",
"author":"施耐庵"
}]
return render_template("control.html",age=age,books=books)
@app.route('/static')
def static_home():
return render_template("static.html")
if __name__ == '__main__': #如果当前文件为主入口,就会往下运行
app.run()
static.html
内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="{{url_for('static',filename='1.jpg')}}" alt="">
</body>
</html>
同时我这里static
文件夹下是有1.jpg
的
接下来访问界面
可以发现成功加载。
接下来加载css,我们在static
文件夹下新建文件夹,命名为css
,在其下创建新文件并命名为style.css
,其内容如下
body{
background-color: pink;
}
而后在static.html
中添加这一句话来进行css加载
<link rel="stylesheet" href="{{ url_for('static',filename='css/style.css')}}">
此时去访问界面
接下来去加载js
,同理,在static
文件夹下创建新文件夹命名为js
,在其内创建新文件命名为myjs.js
,写入内容如下
alert("我是myjs.js中弹出的");
接下来在static.html
中添加一句话
<script src="{{ url_for('static',filename='js/myjs.js') }}"></script>
然后去访问界面