Flask学习笔记(二)

news/2024/12/4 23:48:48/

Flask学习笔记(二)

  • 1.知识点
    • 1.1虚拟环境
      • 1.1.1virtualenv
      • 1.1.2virtualenvwrapper
    • 1.2web与视图
    • 1.3jinja2
      • 1.3.1template知识点
      • 1.3.2豆瓣列表页
      • 1.3.3视图知识点

1.知识点

1.1虚拟环境

1.1.1virtualenv

在系统级python环境下,安装virtualenv虚拟环境。我电脑安装了anconda,所以这一块我就不用操作了。-p参数指定使用系统级的哪一个python.exe 来执行。
win

pip install virtualenv
virtualenv abc#就会在当前地址下新建了一个环境文件夹abc
cd abc/Scripts#进入环境的scripts目录
activate#激活环境

linux

source abc/bin activate#linux是放在bin目录下的

1.1.2virtualenvwrapper

win

pip install virtualenvwrapper-win
mkvirtualenv abc#放在当前win用户的文件夹里面envs的文件夹下
workon abc#激活此环境
deactivate#推出此环境
rmvirtualenv abc#删除此环境
lsvirtualenv abc#列出环境
cdvirtualenv de#立即进入de环境

linux

pip install virtualenvwrapper

1.2web与视图

1.url:scheme://host:port/path/?query-string=xxx#anchor

2.web服务器:负责处理http请求,响应静态文件,常见的有Apache,Nginx以及微软的IIS.

3.应用服务器:负责处理逻辑的服务器。比如php、python的代码,是不能直接通过nginx这种web服务器来处理的,只能通过应用服务器来处理,常见的应用服务器有uwsgi、tomcat等。

4.web应用框架:一般使用某种语言,封装了常用的web功能的框架就是web应用框架,flask、Django以及Java中的SSH(Structs2+Spring3+Hibernate3)框架都是web应用框架。

5.config设置配置文件的四种方式:

app.config['DEBUG'] = True#1.硬编码
app.config.update(DEBUG=True)#2.因为app.config是flask.config.Config的实例,而Config类是继承自dict,因此可以通过update方法
import config
app.config.from_object(config)#3.通过模块对象,将config.py文件的数据导入
app.config.from_pyfile('settings.py',silent=True)#4.也可使用.txt后缀的文件;默认是为False,找不到配置文件就会抛出异常

6.永久性重定向:http的状态码是301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入www.jingdong.com的时候,会被重定向到www.jd.com,因为jingdong.com这个网址已经被废弃了,被改成jd.com,所以这种情况下应该用永久重定向。

7.暂时性重定向:http的状态码是302,表示页面的暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。
8.redirect(url,code=301)#默认是302

1.3jinja2

1.3.1template知识点

1.在渲染模版的时候,默认会从项目根目录下的templates目录下查找模版。也可以在Flask初始化的时候指定template_folder来指定模版的路径。

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

2.当需要渲染的参数比较多时,通过关键字传参方式,给html渲染传参。

@app.route("/key")
def key():context={"a":1,"b":2,"c":3}return render_template("key.html",**context)#==render_template("key.html","a"=1,"b"=2,"c"=3)
<html><head>key</head><title>key</title><body><h1>a={{a}}</h1> <h1>b={{b}}</h1> <h1>c={{c}}</h1> </body>
</html>

3.html中,{{ … }}:用来装载变量,或者字典的key。
{% … %}:用来装载控制语句。
{# … #}:用来装载注释
4.过滤器:通过管道符号(|)进行使用,过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。过滤器官网。

abs(value):返回一个数值的绝对值。 例如:-1|abs。
default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。name|default(‘xiaotuo’)——如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。name
or ‘xiaotuo’
escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。例如:content|escape或content|e。({%autoescape off/on%} XXXXX{%autoescape%}关掉或开启局部转义)
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):计算一个长字符串中单词的个数。

5.自定义过滤器(两种方式)

app.config['TEMPLATES_AUTO_RELOAD']=True
@app.template_filter('cut')
def cut(value):value=value.replace("hello",'')return value
def datetime_format(value,format="%Y年%m月%d日 %H:%M"):return value.strftime(format)
app.add_template_filter(datetime_format,"dformat")#将自定义的datetime_format,以dformat为名添加到app的过滤器中

自定义时间过滤器

@app.route("/time_filter")
def time_filter():now=datetime(2023,6,25,10,53,20)return render_template("key.html",now=now)
@app.template_filter("handle_time")
def handle_time(time):if isinstance(time,datetime):#首先判断是否时时间类型now=datetime.now()timestamp=(now-time).total_seconds()#时间间距if timestamp<60:return "刚刚"elif timestamp>=60 and timestamp<60*60:minutes=timestamp/60return "%s分钟前"%int(minutes)elif timestamp>=60*60 and timestamp<60*60*24:hours=timestamp/(60*60)return "%s小时前"%int(hours)elif timestamp>=60*60*24 and timestamp<60*60*24*30:days=timestamp/(60*60*24)return "%s天前"%int(days)else:return time.strftime('%Y/%m/%d %H:%M')else:return time
<html><body><h1>now is :{{now|handle_time}}</h1> </body>
</html>

6.for循环(for ,else ,endfor,if),不可以使用continue和break表达式来控制循环的执行

   {% for user in users %}<li>{{ user.username}}</li>{% else %}<li>no users found</li>{% endfor %}{% for y in range(1,10) if y<x%}{#y从1开始循环,当不满足y<x时,就会跳出循环#}
参数说明
loop.index当前迭代的索引(从1开始)
loop.index0当前迭代的索引(从0开始)
loop.first是否是第一次迭代,返回True或False
loop.last是否是最后一次迭代,返回True或False
loop.length序列的长度

用for循环写一个99乘法表。

@app.route("/mul")
def mul():return render_template('/mul.html')
<table border="1"><tbody>{% for x in range(1,10) %}<tr>{% for y in range(1,x+1) %}<td>{{y}}*{{x}}={{x*y}}</td>{%endfor%}</tr>{%endfor%}</tbody>
</table>

7.宏:模板中的宏跟python中的函数类似,可以传递参数,但是不能有返回值,可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量。

{% macro INPUT(name="",value="",type="text") %}{# 定义一个INPUT函数 #}<input name="{{name}}" value="{{value}}" type="{{type}}">
{% endmacro %}<table><tr><td>用户名</td><td>{{INPUT("username")}}</td></tr><tr><td>密码</td><td>{{INPUT("password",type="password")}}</td></tr><tr><td></td><td>{{INPUT(value="提交",type="submit")}}</td></tr>
</table>

8.导入宏

{% import 'forms.html' as forms %}
{% from 'forms.html' import input as input_field, textarea %}

如果你想要导入一个需要访问当前上下文变量的宏,有两种可能的方法:
A.显式地传入请求或请求对象的属性作为宏的参数。
B.与上下文一起(with context)导入宏。

{% from '_helpers.html' import my_macro with context %}

9.include语句可以把一个模板引入到另外一个模板中,类似于把一个模板的代码copy到另外一个模板的指定位置

{% include 'header.html' %}主体内容
{% include 'footer.html' %}

10.set语句:在模版中,可以使用set语句来定义全局变量。

{% set username='你好' %}
<p>用户名:{{ username }}</p>

11.with语句:定义局部变量。

{% with classroom = '你好' %}
<p>班级:{{ classroom }}</p>
{% endwith %}
{% with %}{% set classroom = '你好' %}<p>班级:{{ classroom }}</p>
{% endwith %}

12.继承:默认情况下,子模板如果实现了父模版定义的block。那么子模板block中的代码就会覆盖掉父模板中的代码。如果想要在子模板中仍然保持父模板中的代码,那么可以使用{{ super() }}来实现。

{% block body_block %}<p style="background: red;">这是父模板中的代码</p>{% endblock %}
{% block body_block %}{{ super() }}<p style="background: green;">我是子模板中的代码</p>
{% endblock %}

如果想要在模版中使用其他模版中的其他代码。那么可以通过{{ self.其他block名字() }}就可以了。

{% block title %}首页
{% endblock %}{% block body_block %}{{ self.title() }}<p style="background: green;">我是子模板中的代码</p>
{% endblock %}

1.3.2豆瓣列表页

在这里插入图片描述

1.3.3视图知识点

1.添加url与视图函数的映射: app.add_url_rule(rule,endpoint=None,view_func=None)。如果没有填写endpoint,那么默认会使用view_func的名字作为endpoint。以后在使用url_for的时候,就要看在映射的时候有没有传递endpoint参数,如果传递了,那么就应该使用endpoint指定的字符串,如果没有传递,那么就应该使用view_func的名字。 @app.route(rule,**options)装饰器:这个装饰器底层,其实也是使用add_url_rule来实现url与视图函数映射的。
2.类视图:支持继承,但是不能跟函数视图一样,写完类视图还需要通过app.add_url_rule(url_rule,view_func)来进行注册。必须继承自flask.views.View.,必须实现dipatch_request方法,以后请求过来后,都会执行这个方法。
标准类视图:

from flask import views,jsonify
class JSONView(views.View):#父类,格式化输出为json格式def get_data(self):raise NotImplementedErrordef dispatch_request(self):return jsonify(self.get_data())class lei_view(JSONView):#子类def get_data(self):return {"username":"xiaoming","password":"123"}app.add_url_rule("/lei/",endpoint="lei",view_func=lei_view.as_view('lei'))

基于请求方法的类视图:继承于views.MethodView。

class LoginView(views.MethodView):def get(self,error=None):return render_template("macro.html",error=error)def post(self):username=request.form.get('username')password=request.form.get('password')print(username,password)if username=="xiaoming" and password=="123":return  "登陆成功"else:return self.get(error="用户名或密码错误")
app.add_url_rule("/mylogin/",view_func=LoginView.as_view('my_login'))

3 类视图中的装饰器
函数视图:自己定义的装饰器必须放在app.route下面。否则这个装饰器就起不到任何作用。
类视图:类内定义类属性decorators,这个类属性是一个列表或者元组都可以,里面装的就是所有的装饰器。
4.蓝图

from flask import Blueprintuser_bp = Blueprint('user',__name__)
from blueprints.user import user_bpapp.regist_blueprint(user_bp)```
#如果想要某个蓝图下的所有url都有一个url前缀,那么可以在定义蓝图的时候,指定url_prefix参数
user_bp = Blueprint('user',__name__,url_prefix='/user/')

A.在定义url_prefix的时候,要注意后面的斜杠,如果给了,那么以后在定义url与视图函数的时候,就不要再在url前面加斜杠了。
B.如果项目中的templates文件夹中有相应的模版文件,就直接使用了。如果没有,那么就到在定义蓝图的时候指定的路径中寻找。并且蓝图中指定的路径可以为相对路径,相对的是当前这个蓝图文件所在的目录。

news_bp = Blueprint('news',__name__,url_prefix='/news',template_folder='xxx')

C.蓝图中静态文件的查找规则:
* 在模版文件中,加载静态文件,如果使用url_for(‘static’),那么就只会在app指定的静态文件夹目录下查找静态文件。
* 如果在加载静态文件的时候,指定的蓝图的名字,比如news.static,那么就会到这个蓝图指定的static_folder下查找静态文件(相对于这个蓝图位置的地址)。

news_bp = Blueprint('news',__name__,url_prefix='/news',template_folder='xxx',static_folder='blue_static')

D.url_for反转蓝图中的视图函数为url:
* 如果使用蓝图,那么以后想要反转蓝图中的视图函数为url,那么就应该在使用url_for的时候指定这个蓝图。比如news.news_list。否则就找不到这个endpoint。在模版中的url_for同样也是要满足这个条件,就是指定蓝图的名字。
* 即使在同一个蓝图中反转视图函数,也要指定蓝图的名字。
E.蓝图实现子域名:
需要在主app文件中,需要配置app.config的SERVER_NAME参数。app.config['SERVER_NAME'] = 'jd.com:5000'
在创建蓝图对象的时候,需要传递一个subdomain参数,来指定这个子域名的前缀。例如:
cms_bp = Blueprint('cms',__name__,subdomain='ccc')
C:\Windows\System32\drivers\etc下,找到hosts文件,然后添加域名与本机的映射。
域名和子域名都需要做映射。

127.0.0.1 jd.com
127.0.0.1 ccc.jd.com


http://www.ppmy.cn/news/689084.html

相关文章

外星人aw768键盘设置快捷键

原来快捷键是通过拖拽的方式设置的

射杀外星人python实验_Python系统学习 - 项目篇(消灭外星人3)

哇&#xff5e;都这么久了&#xff0c;唉都怪广东这个天气&#xff0c;总是下雨&#xff0c;让人心情都变得沉闷&#xff0c;难搞哦&#xff0c;&#xff08;其实主要还是工作原因&#xff0c;累死个人&#xff0c;剥削 10086&#xff09; 今天我们学习了消灭外星人都最重要都…

python外星人入侵加入声音_《python从入门到实践》项目一:外星人入侵

游戏编程思维导图游戏思路函数编写第一次做思维导图&#xff0c;做的有点乱 解释&#xff1a;跟着《python编程从入门到实践》写完游戏程序后&#xff0c;写一下自己的心得体会。可以把这个游戏分为几块来理解。如果想要设计一款小游戏&#xff0c;第一是对游戏的屏幕进行设置&…

射杀外星人python实验_Python 项目实践一(外星人入侵小游戏)第二篇

接着上次的继续学习。 一 创建一个设置类 每次给游戏添加新功能时&#xff0c;通常也将引入一些新设置。下面来编写一个名为settings的模块&#xff0c;其中包含一个名为Settings的类&#xff0c;用于将所有设置存储在一个地方&#xff0c;以免在代码中到处添加设置。这样&am…

外星人入侵(二)

飞船的移动 思路:当按下特定的方向键后&#xff0c;飞船向指定的方向移动&#xff0c;可以允许不断移动&#xff0c;为实现不断移动&#xff0c;需要设置一个移动标志&#xff0c;默认为False&#xff0c;当按下时&#xff0c;则为True&#xff0c;实现其方向键的移动&#xff…

外星人移动

alien_invasion.py import sysimport pygamefrom pygame.sprite import Group from settings import Settings from ship import Ship from alien import Alien import game_functions as gfdef run_game():#初始化游戏并创建一个屏幕对象pygame.init()ai_settings Settings(…

python 外星人游戏怎么打开_Python外星人入侵游戏开发—创建游戏窗口

第1、2行代码:导入了模块sys 和pygame 。模块pygame 包含开发游戏所需的功能。玩家退出时,我们将使用模块sys 来退出游戏。 第3行至19行,是函数run_game()的实现。 第5行,代码行pygame.init() 初始化背景设置,让Pygame能够正确地工作。 第6行,我们调用pygame.display.…

怎么运行python外星人入侵_Python入门项目:外星人入侵

前言 作为一个编程小白选手&#xff0c;经过一段时间的基础语法学习&#xff0c;终于迎来了首个项目学习&#xff0c;从一步步的模仿到理解到每个步骤的思路想法&#xff0c;每个类之间的联系与构造&#xff0c;还有些编程中的一些小细节&#xff0c;如何养成一个编程的好习惯…