Flask全套知识点从入门到精通,学完可直接做项目(二)

本文涉及的产品
.cn 域名,1个 12个月
简介: Flask全套知识点从入门到精通,学完可直接做项目

流程控制-选择结构

image.png

所有的控制语句都是放在 {% ... %} 中,并且有一个语句 {% endxxx %} 来进 行结束!

if:if语句和python中的类似,可以使用 >,=,==,!= 来进行判 断,也可以通过 and,or,not,() 来进行逻辑合并操作

{% if age >= 18 %}
    <p>{{ age }}岁,成年人,可以通宵打游戏</p>
{% else %}
    <p>{{ age }}岁,未成年人,可以通宵学习</p>
{% endif %}

注意

if 条件判断语句必须放在 {% if statement %} 中间,并且还必须有结束 的标签 {% endif %} 。

流程控制-循环结构

image.png

for...in... for循环可以遍历任何一个序列包括列表、字典、元组。并且 可以进行反向遍历,以下将用几个例子进行解释:

列表

<ul>
   {% for user in users%}
       <li>{{ user}}</li>
   {% endfor %}
</ul>

遍历字典

<tr>
   {% for key in person.keys() %}
        <td>{{ key}}</td>
   {% endfor %}
</tr>
<tr>
    {% for val in person.values() %}
        <td>{{ val}}</td>
   {% endfor %}
</tr>
<tr>
   {% for item in person.items() %}
        <td>{{ item}}</td>
   {% endfor %}
</tr>
<tr>
   {% for key,value in person.items() %}
        <td>{{ value}}</td>
   {% endfor %}
</tr>

如果序列中没有值的时候,进入else 反向遍历用过滤器 reverse:

<ul>
   {% for user in users|reverse %}
       <li>{{ user}}</li>
   {% else %}
        <li>没有任何用户</li>
   {% endfor %}
</ul>

并且Jinja中的for循环还包含以下变量,可以用来获取当前的遍历状 态:

image.png

总结

在 jinja2 中的 for 循环,跟 python 中的 for 循环基本上是一模一样的 也是 for...in... 的形式。并且也可以遍历所有的序列以及迭代器 唯一不同的是, jinja2 中的 for 循环没有 break 和 continue 语句

导入模板include

image.png

1. 这个标签相当于是直接将指定的模版中的代码复制粘贴到当前位 置。


2. include 标签,如果想要使用父模版中的变量,直接用就可以了,不 需要使用 with context 。


3. include 的路径,也是跟 import 一样,直接从 templates 根目录下去找, 不要以相对路径去找。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SXT</title>
</head>
<body>
    <!--通过include 引入头部log信息-->
   {% include "common/head.html" %}
    <div>
        这是首页内容
       {{ major }}
    </div>
    <hr>
   <!--通过include 引入底部版权信息-->
   {% include "common/footer.html" %}
</body>
</html>

set与with标签

image.png

set的使用

在模版中,可以使用 set 语句来定义变量

<!--set语句来定义变量,之后,那么在后面的代码中,都可以使用这个变量-->
{% set uname='sxt'%}
<p>用户名:{{ uname }}</p>

一旦定义了这个变量,那么在后面的代码中,都可以使用这个变 量,就类似于Python的变量定义是一样的

with语句

with 语句定义的变量,只能在 with 语句块中使用,超过了这个代码 块,就不能再使用了

<!--with语句来定义变量,只有在指定区域 才能使用这个变量-->
{% with classroom='python202'%}
    <p>班级:{{ classroom }}</p>
{% endwith %}

注意

关于定义的变量, with 语句也不一定要跟一个变量, 可以定义一个空的 with 语句, 需要在指定的区域才能使用的情况,可以set与with组合使用。

{% with %}
 {% set  pname='李思思' %}
   <p>娱乐县县长:{{ pname }}</p>
{% endwith %}

静态文件

image.png

静态文件:css文件 js文件 图片文件等文件

加载静态文件使用的是 url_for 函数。然后第一个参数需要为 static ,第 二个参数需要为一个关键字参数 filename='路径' 。

语法

{{ url_for("static",filename='xxx') }}

image.png

注意 路径查找,要以当前项目的 static 目录作为根目录

模板继承

image.png

为什么需要模版继承

模版继承可以把一些公用的代码单独抽取出来放到一个父模板中 以后子模板直接继承就可以使用了。 这样可以重复的利用代码,并且以后修改起来也比较方便

image.png

模版继承语法

使用 extends 语句,来指明继承的父模板。父模板的路径,也是相对 于 templates 文件夹下的绝对路径

{% extends "base.html" %}

block语法

一般在父模版中,定义一些公共的代码。子模板可能要根据具体的 需求实现不同的代码。这时候父模版就应该有能力提供一个接口,让子模板来实现。从而 实现具体业务需求的功能。

父模板

{% block block的名字 %}
{% endblock %}

子模板

1. {% block block的名字 %}
2. 子模板中的代码
3. {% endblock %}

调用父模版代码block中的代码

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

父模板

{% block block_body %}
    <p style="background-color: blue">我是父模版block_body处的内容</p>
{% endblock %}

子模板

1. {% block block_body%}
2.      {{ super() }}
3. <p style="background-color: green">我是子模版block_body处的内容</p>
4. {% endblock %}

调用另外一个block中的代码

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


{% block title %}
     sxt首页
{% endblock %}
{% block block_body%}
   {{ self.title() }}
    <p style="background-color: green">我是子模版block_body处的内容</p>
{% endblock %}

注意

1. 子模板中的代码,第一行,应该是 extends

2. 子模板中,如果要实现自己的代码,应该放到block中。如果 放到其他地方,那么就不会被渲染

Flask视图

add_url_rule与app.route

add_url_rule


add_url_rule(rule,endpoint=None,view_func=None)


这个方法用来添加url与视图函数的映射。 如果没有填写 endpoint ,那么默认会使用 view_func 的名字作为 endpoint 。 以后在使用 url_for 的时候,就要看在映射的时候有没有传递 endpoint 参 数,如果传递了,那么就应该使用 endpoint 指定的字符串, 如果没有传递,那么就应该使用 view_func 的名字。

def my_list():
 return "我是列表页"
app.add_url_rule('/list/',endpoint='sxt',view_func=my_list)

app.route原理剖析

这个装饰器底层,其实也是使用 add_url_rule 来实现url与视图函数映射 的。

from flask import Flask,url_for
app = Flask(__name__)
@app.route('/',endpoint='index')
def index():
    print(url_for('show'))
    print(url_for('index'))
    return "Hello"
def show_me():
    return "这个介绍信息!!"
# endpoint 没有设置,url_for中就写函数的名字,如果设置了,就写endpoint的值
app.add_url_rule('/show_me',view_func=show_me,endpoint='show')  
# @app.route 底层就是使用的 add_url_rule
if __name__ =='__main__':
    app.run(debug=True)

类视图

image.png

之前我们接触的视图都是函数,所以一般简称函数视图。 其实视图也可以基于类来实现,类视图的好处是支持继承, 但是类视图不能跟函数视图一样,写完类视图还需要通过 app.add_url_rule(url_rule,view_func) 来进行注册


标准类视图使用步骤


1. 标准类视图,必须继承自 flask.views.View


2. 必须实现 dispatch_request 方法,以后请求过来后,都会执行这个方 法。 这个方法的返回值就相当于是之前的视图函数一样。也必须返回 Response 或者子类的对象,或者是字符串,或者是元组。


3. 必须通过 app.add_url_rule(rule,endpoint,view_func) 来做url与视图的映射。 view_func 这个参数,需要使用类视图下的 as_view 类方法类转换: ListView.as_view('list') 。


4. 如果指定了 endpoint ,那么在使用 url_for 反转的时候就必须使用 endpoint 指定的那个值。如果没有指定 endpoint ,那么就可以使用 as_view(视图名字) 中指定的视图名字来作为反转。

from flask import Flask,url_for
from flask.views import View
app= Flask(__name__)
@app.route('/')
def index():
    # print(url_for('mylist'))
    print(url_for('my'))
    return 'Hello'
class ListView(View):
    def dispatch_request(self):
        return '返回了一个List的内容!!'
# app.add_url_rule('/list',view_func=ListView.as_view('mylist'))
app.add_url_rule('/list',endpoint='my',view_func=ListView.as_view('mylist'))
# 用于测试
with app.test_request_context():
    print(url_for('my'))
if __name__ =='__main__':
    app.run(debug=True)

类视图的好处

1.可以继承,把一些共性的东西抽取出来放到父视图中,子视图直 接拿来用就可以了。

2.但是也不是说所有的视图都要使用类视图,这个要根据情况而 定。视图函数用得最多。

from flask import Flask,jsonify
from flask.views import View
app = Flask(__name__)
# 需求:返回的结果都必须是json数据
class BaseView(View):
    def get_data(self):
        raise NotImplementedError
    def dispatch_request(self):
        return jsonify(self.get_data())
class JsonView(BaseView):
    def get_data(self):
        return {'uname':'吕布','age':20}
class Json2View(BaseView):
    def get_data(self):
        return [
           {'name':'zs','lua':'Python'},
           {'name':'lisi','lua':'Python'},
       ]
app.add_url_rule('/base',view_func=BaseView.as_view('base'))
app.add_url_rule('/json',view_func=JsonView.as_view('json'))
app.add_url_rule('/json2',view_func=Json2View.as_view('json2'))
if __name__ =='__main__':
    app.run(debug=True)

基于调度方法的类视图

image.png

1. 基于方法的类视图,是根据请求的 method 来执行不同的方法的。 如果用户是发送的 get 请求,那么将会执行这个类的 get 方法。 如果用户发送的是 post 请求,那么将会执行这个类的 post 方法。其他 的method类似,比如 delete 、 put


2. 这种方式,可以让代码更加简洁。所有和 get 请求相关的代码都放 在 get 方法中,所有和 post 请求相关的代码都放在 post 方法中。就不 需要跟之前的函数一样,通过 request.method == 'GET'

class  LoginView(views.MethodView):
    def get(self,error=None):
        return
render_template('login.html',error=error)
    def post(self):
        #模拟实现
        #拿到前端页面传过来的 账号 和密码 去数据库做查询操作 查询到 (跳转主页面) ,反之跳转到login.html页面并给出错误提示信息
        uname = request.form['uname']
        pwd = request.form['pwd']
        if  uname=="sxt"  and  pwd =="123":
            return render_template('index.html')
        else:
            return  self.get(error="用户名或者密码错误")
# 注册类视图
app.add_url_rule('/login/',view_func=LoginVi
ew.as_view('my_login'))

HTML

<form action="/login/"  method="post">
    <table>
        <tr>
            <td>账号:</td>
            <td><input type="text" name="uname"></td>
        </tr>
         <tr>
            <td>密码:</td>
            <td><input type="password" name="pwd"></td>
        </tr>
          <tr>
            <td></td>
            <td><input type="submit" value="立即登录"></td>
        </tr>
         <tr>
            <td colspan="2">
               {# <font  color="red">{{ error }}</font>#}
                {# 优化写法 :判断 #}
               {% if error %}
                   <font  color="red">{{ error }}</font>
               {% endif %}
            </td>
        </tr>
    </table>
</form>

装饰器

image.png

简言之,python装饰器就是用于拓展原来函数功能的一种函数,这 个函数的特殊之处在于它的返回值也是一个函数, 使用python装饰器的好处就是在不用更改原函数的代码前提下给函 数增加新的功能。


1. 在视图函数中使用自定义装饰器,那么自己定义的装饰器必须放 在 app.route 下面。 否则这个装饰器就起不到任何作用。


案例1


需求:查看设置个人信息时,只有检测到用户已经登录了才能查 看,若没有登录,则无法查看并给出提示信息


定义装饰器

def login_required(func):
    @wraps(func)
    def wrapper(*arg,**kwargs):
        uname = request.args.get('uname')
        pwd = request.args.get('pwd')
        if uname == 'zs' and pwd == '123':
            logging.info(f'{uname}:登录成功')
            return func(*arg,**kwargs)
        else:
            logging.info(f'{uname}:尝试登录,但没成功')
            return '请先登录'
    return wrapper

使用装饰器

@app.route('/settings/')
@login_requierd
def settings():    
    return '这是设置界面'

2. 在类视图中使用装饰器,需要重写类视图的一个类属性 decorators , 这个类属性是一个列表或者元组都可以,里面装的就是所有的装饰 器。

案例2

需求: 查看设置个人信息时,只有检测到用户已经登录了才能查看, 若没有登录,则无法查看并给出提示信息

使用装饰器

class  ProfileView(views.View):    
    decorators = [login_requierd]    
    def dispatch_request(self):        
        return '这是个人中心界面'
app.add_url_rule('/profile/',view_func=ProfileView.as_view('profile'))

蓝图介绍

在Flask中,使用蓝图Blueprint来分模块组织管理。 蓝图实际可以理解为是存储一组视图方法的容器对象,其具有如下 特点:


一个应用可以具有多个Blueprint

可以将一个Blueprint注册到任何一个未使用的URL下比如 “/user” 、 “/goods”

Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应 用的视图和函数的

在一个应用初始化时,就应该要注册需要使用的Blueprint

注意

Blueprint并不是一个完整的应用,它不能独立于应用运行,而 必须要注册到某一个应用中

使用方式

使用蓝图可以分为三个步骤

  • 1 创建一个蓝图对象
user_bp=Blueprint('user',__name__)
  • 在这个蓝图对象上,
1. @user_bp.route('/')
2. def user_profile():
3. return 'user_profile'
  • 在应用对象上注册这个蓝图对象
app.register_blueprint(user_bp)

指定蓝图的url前缀

在应用中注册蓝图时使用 url_prefix 参数指定

app.register_blueprint(user_bp,url_prefix='/user')
app.register_blueprint(goods_bp,url_prefix='/goods')

蓝图的目录结构

为了让项目代码更加清晰,可以通过将代码分在不同的文件里进行 管理

根据功能模块

对于一个打算包含多个文件的蓝图,通常将创建蓝图对象放到 Python包的 __init__.py 文件中

--------- project # 工程目录
  |------ main.py # 启动文件
  |------ user  #用户蓝图
  |  |--- __init__.py  # 此处创建蓝图对象
  |  |--- view.py  
  |  |--- ...
  |------ goods # 商品蓝图
  |  |--- __init__.py
  |  |--- ...
  |...

根据技术模块

--------- project # 工程目录
  |------ main.py # 启动文件
  |------ view  #用户蓝图
  |  |--- user.py  # 此处创建蓝图对象
  |  |--- item.py  
  |  |--- view.py
  |  |--- ...
  |...

蓝图中模版文件

image.png

寻找规则

  • 如果项目中的templates文件夹中有相应的模版文件,就直接使 用了。
  • 如果项目中的templates文件夹中没有相应的模版文件,那么就 到在定义蓝图的时候指定的路径中寻找。
  • 并且蓝图中指定的路径可以为相对路径,相对的是当前这个蓝图文件所在的目录

 image.png

因为这个蓝图文件是在user/view.py,那么就会到blueprints这个 文件夹下的user_page文件夹中寻找模版文件。


小总结: 常规:蓝图文件在查找模版文件时,会以templates为根目录进行 查找


注意


1 个性化coder喜欢在【创建蓝图对象的时候】 指定 模版文 件的查找路径,如下 news_bp =Blueprint('news',__name__,url_prefix='/news',template_folder='news_page')

2 只有确定templates目录下没有对应的 html文件名的时候, 才会去蓝图文件指定的目录下查找,指定才会生效

3 若templates目录下,有一个与蓝图文件指定的目录下同名 的一个 html文件时,优先走templates目录下的东西

蓝图中静态文件

image.png

蓝图内部静态文件 蓝图对象创建时不会默认注册静态目录的路由。需要我们在创建时 指定 static_folder 参数。 下面的示例将蓝图所在目录下的 static_admin 目录设置为静态目录:

user=Blueprint("user",__name__,static_folder='user_static')
app.register_blueprint(admin,url_prefix='/user')

也可通过 static_url_path 改变访问路径

user =Blueprint('user',__name__,template_folder='user_page',static_folder='user_static',static_u
rl_path='/static')
app.register_blueprint(user,url_prefix='/user')

总结 【掌握】查找方式1:查找静态文件时,正常情况下,会以 static为根目录进行查找 【了解】查找方式2:查找静态文件时,非正常情况下,需要用 url_for('蓝图的名字.static'),然后会去蓝图对象在创建时指定的 静态文件夹目录下 去查找静态文件

蓝图url_for函数

image.png

如果使用蓝图,那么以后想要反转蓝图中的视图函数为url,就应该 在使用url_for的时候指定这个蓝图名字。 app类中、模版中、同一个蓝图类中都是如此。否则就找不到这个 endpoint

html文件中

<a href="{{ url_for('user.user_list')}}">新闻列表 OK写法</a>
{# <a href="{{ url_for('user_list')}}">新闻列表 no Ok写法</a>#}

python文件中

from flask import
Blueprint,render_template,url_for
user_bp=Blueprint('news',__name__,url_prefix='/user',template_folder='user_page',static_folder='user_static')
@user_bp.route('/list/')
def user_list():    
    #如下写法:才找得到 url_for('蓝图名称.方法名')
    print(url_for('user.user_list'))  #/user/list/    
    print(url_for('user.user_detail'))  #/user/detail/    
    return render_template('user_list.html')
@user_bp.route('/detail/')
def user_detail():    
    return '用户详情页面'

子域名实现

蓝图实现子域名:

1. 使用蓝图技术。

2. 在创建蓝图对象的时候,需要传递一个 subdomain 参数,来指定这 个子域名的前缀。

cms_bp=Blueprint('cms',__name__,subdomain='cms')

3. 需要在主app文件中,需要配置app.config的SERVER_NAME参 数。例如:

app.config['SERVER_NAME']='baidu.com:5000'

4. 在windows: C:\Windows\System32\drivers\etc 下,找到hosts文件,然后添 加域名与本机的映射。Linux: /etc/hosts 域名和子域名都需要做映射

注意 ip地址不能有子域名 localhost也不能有子域名

Flask高级

Flask设置Cookie

image.png

设置

设置cookie是在Response的对象上设置。 flask.Response 对象有一个 set_cookie 方法,可以通过这个方法来设置 cookie 信息。

key,value形式设置信息

from flask import Flask, make_response
app = Flask(__name__)
@app.route('/cookie')
def set_cookie():
    resp = make_response('set cookie ok')
    resp.set_cookie('uname', 'itbaizhan')
    return resp

查看Cookie

在Chrome浏览器中查看cookie的方式:

方式1:借助于 开发调式工具进行查看

方式2:在Chrome的设置界面->高级设置->内容设置->所有 cookie->找到当前域名下的cookie。

from flask import request
@app.route('/get_cookie')
def get_cookie():
    resp = request.cookies.get('uname')
    return resp

删除cookie

方式1:通过 Response对象.delete_cookie ,指定cookie的key,就可以删 除cookie了。

from flask import request
@app.route('/delete_cookie')
def delete_cookie():
    response = make_response('helloworld')
    response.delete_cookie('uname')
    return response

方式2:在客户端浏览器人为的删除(清除浏览器浏览历史记录 后,很多网站之前免密登录的都不好使了)


Cookie的有效期


默认的过期时间:如果没有显示的指定过期时间,那么这个cookie 将会在浏览器关闭后过期。 max_age:以秒为单位,距离现在多少秒后cookie会过期。


expires:为datetime类型。这个时间需要设置为格林尼治时间, 相对北京时间来说 会自动+8小时 如果max_age和expires都设置了,那么这时候以max_age为标 准。

注意

max_age在IE8以下的浏览器是不支持的。 expires虽然在新版的HTTP协议中是被废弃了,但是到目前为 止,所有的浏览器都还是能够支持,所以如果想要兼容IE8以下 的浏览器,那么应该使用expires,否则可以使用max_age。

from flask import Flask,Response
app = Flask(__name__)
@app.route('/')
def index():
   return 'Hello!!'
@app.route('/create_cookie/defualt/')
def create_cookie1():
    resp = Response('通过默认值,设置cookie有效期')
   # 如果没有设置有效期,默认会在浏览器关闭的时候,让cookie过期
   resp.set_cookie('uname','zs')
   return resp
@app.route('/create_cookie/max_age/')
def create_cookie2():
   resp = Response('通过max_age,设置cookie有效期')
   # max_age以秒为单位设置cookie的有效期
   age = 60*60*2
   resp.set_cookie('uname','zs',max_age=age)
   return resp
from datetime import datetime
@app.route('/create_cookie/expires/')
def create_cookie3():
   resp = Response('通过expires,设置cookie有效期')
   # expires 以指定时间为cookie的有效期
   # 16+8 == 24
   tmp_time = datetime(2021, 11,11,hour=18,minute=0,second=0)
   resp.set_cookie('uname','python',expires=tmp_time)
   return resp
from datetime import timedelta
@app.route('/create_cookie/expires2/')
def create_cookie4():
   resp = Response('通过expires,设置cookie有效期')
   # expires 以指定时间为cookie的有效期
   tmp_time = datetime.now() +timedelta(days=2)
   resp.set_cookie('uname','python_sql',expires=tmp_time)
   return resp
@app.route('/create_cookie/exp_max/')
def create_cookie5():
   resp = Response('通过expires与max_age,设置cookie有效期')
   # expires 与max_age同时设置了,会以max_age为准
   tmp_time = datetime.now() +timedelta(days=2)
   resp.set_cookie('uname','python_sql',expires=tmp_time,max_age = 60*60*2)
   return resp
if __name__ == '__main__':
    app.run(debug=True)


目录
相关文章
|
5月前
|
缓存 前端开发 JavaScript
flask各种版本的项目,终端命令运行方式的实现
flask各种版本的项目,终端命令运行方式的实现
196 4
|
5月前
|
数据可视化 API 开发者
通俗易懂:一步步教你 Flask 项目自动生成 API 文档
Flasgger,作为一款强大的 Flask 扩展,自动从 Flask 应用中提取并生成 OpenAPI 规范文档,配备 SwaggerUI,为开发者提供了一条快捷通道,让 API 的文档编制和交互式测试变得简单易行。Flasgger 的设计原则是简化开发流程,通过与 Flask 框架的无缝整合,让开发者可以更专注于应用逻辑的构建。
|
2月前
|
Linux Python
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
|
3月前
|
安全 前端开发 API
震惊!掌握Django/Flask后,我竟然轻松征服了所有Web项目难题!
【7月更文挑战第15天】Python Web开发中,Django以其全面功能见长,如ORM、模板引擎,助你驾驭复杂需求;Flask则以轻量灵活取胜,适合快速迭代。两者结合使用,无论是数据库操作、用户认证还是API开发,都能让你应对Web挑战游刃有余。掌握这两者,Web项目难题变得易如反掌!
65 10
|
4月前
|
数据处理 Python
Flask 项目工程目录层级划分
本文介绍了如何将 Flask 项目工程目录层级按照主题分类划分,主要包括模型层、视图层、表单层、模板文件和静态文件。通过合理地组织项目文件,可以提高项目的可读性、可维护性和可扩展性。
60 5
|
5月前
|
数据库连接 Python
Flask 框架入门与实践:构建你的第一个 Web 应用
【5月更文挑战第18天】本文介绍了使用 Flask 框架构建第一个 Web 应用的步骤。首先通过 `pip install Flask` 安装框架,然后编写基本的 Python 代码创建应用,包括定义路由和响应。示例展示如何显示 &quot;Hello, World!&quot;,并扩展到显示用户信息的功能。利用模板(如 `index.html`)可使页面更丰富。随着学习深入,可以利用 Flask 的更多特性,如表单处理和数据库连接,来构建更复杂的 Web 应用。本文旨在激发读者对 Flask 和 Web 开发的兴趣,鼓励不断探索和实践。
111 7
|
4月前
|
前端开发 索引 Python
【已解决】Flask项目报错TypeError: tuple indices must be integers or slices, not str
【已解决】Flask项目报错TypeError: tuple indices must be integers or slices, not str
48 0
|
5月前
|
前端开发 JavaScript 数据库
Flask狼书笔记 | 09_图片社交网站 - 大型项目的架构与需求(2)
9.8 收藏图片 前面已经学习过如何使用关联表来表示多对多关系,缺点是只能表示关系,不能存储数据(如我还想记录下收藏图片的时间戳)。这种情况下,我们可以使用关联模型来表示多对多关系。 在关联模型中,我们将Photo模型与User模型的多对多关系,分离成了User模型和Collect模型的一对多关系,和Photo模型与Collect模型的一对多关系。
125 0
|
5月前
|
开发者 索引 Python
Flask环境搭建与项目初始化
【4月更文挑战第15天】本文指导如何搭建Flask开发环境并初始化项目。首先确保安装Python,然后通过pip安装Flask。创建名为`myflaskapp`的项目目录,包含`app.py`入口文件。在`app.py`中初始化Flask应用,定义路由和视图函数。运行`python app.py`启动开发服务器,访问`http://127.0.0.1:5000/`查看结果。完成基本设置后,可按需求扩展应用功能。
|
5月前
|
Python
通过命令行的方式快速创建一个flask项目
通过命令行的方式快速创建一个flask项目
145 0