Flask之显示用户小案例、配置文件、路由系统

显示用户小案例

注意

  1. request是全局: request.method
  2. request.form:前端post提交的数据
  3. request.args:前端get请求提交的数据
  4. 路由注册是使用装饰器:@app.route('/detail/')
  5. 路由有转换器:int
    /detail/<int:pk>
    /detail/?pk=1
    
  6. 新手四件套
    return '字符串'
        return render_template('index.html', user_dict=USERS)
        return redirect('/login')
        return jsonify(字典,列表)
    
  7. session的使用–全局导入–必须加秘钥
    放值:session['key']=value
    取值:session.get('key')
  8. 只要函数被装饰器装饰器了,以后被装饰的函数,就都叫 inner了
    • 只要在路由装饰器上加endpoint属性,就可以解决这个问题
    • endpoint等同于djagno路由中的name --》给路由命别名—》可以通过反向解析,通过名字找到路径’
  9. url_for 做路由反向解析 ⇢ \dashrightarrow 需要使用endpoint指定的名字

代码

from flask import Flask, request, render_template, redirect, session, url_for

app = Flask(__name__)

# 如果要用session,必须加这一句
app.secret_key = 'asdfasdfasdf-lqz-justin'

USERS = {
    1: {'name': '李清照', 'age': 18, 'gender': '男',
        'text': "刘亦菲,1987年8月25日出生于湖北省武汉市,华语影视女演员、歌手,毕业于北京电影学院2002级表演系本科",
        'img': 'https://img2.woyaogexing.com/2021/10/16/e3ccba623848430ba83209c0621a2256!400x400.jpeg'},
    2: {'name': '彭于晏', 'age': 28, 'gender': '男',
        'text': "彭于晏,1982年3月24日出生于中国台湾省澎湖县,毕业于不列颠哥伦比亚大学,华语影视男演员。。。。。。。。",
        'img': 'https://img2.woyaogexing.com/2021/10/16/e71aa35728c34313bccb4c371192990f!400x400.jpeg'},
    3: {'name': '迪丽热巴', 'age': 38, 'gender': '女',
        'text': "迪丽热巴(Dilraba),1992年6月3日出生于中国新疆乌鲁木齐市,毕业于上海戏剧学院,中国内地影视女演员",
        'img': 'https://img2.woyaogexing.com/2021/10/30/6a34146dde2d4f1c832463a5be1ed027!400x400.jpeg'},
    4: {'name': '亚瑟', 'age': 38, 'gender': '男',
        'text': "亚瑟,是腾讯手游《王者荣耀》中一名战士型英雄角色,也是《王者荣耀》的新手英雄之一,既可攻又可守",
        'img': 'https://img2.woyaogexing.com/2021/10/30/371b2aa7a03c4f53b7b1bc86f877d7d1!400x400.jpeg'},
}


def auth(func):
    def inner(*args, **kwargs):
        username = session.get('username')
        if username:
            res = func(*args, **kwargs)
            return res
        else:
            return redirect(url_for('login'))

    return inner


@app.route('/login', methods=['GET', 'POST'], endpoint='login')
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        username = request.form.get('username')
        password = request.form.get('password')
        if username == 'cai' and password == '123':
            session['username'] = username
            # 登录成功,重定向到首页
            return redirect('/')
        else:
            return render_template('login.html', error='用户名或密码错误')


@app.route('/', methods=['GET'], endpoint='index')
@auth
def index():
    return render_template('index.html', user_dict=USERS)


@app.route('/detail/')
@auth
def detail(pk):
    user = USERS.get(pk)
    return render_template('detail.html', user=user)
login.html
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <title>Titletitle>
head>
<body>
<div class="container col-xl-10 col-xxl-8 px-4 py-5">
    <div class="row align-items-center g-lg-5 py-5">
        <div class="col-lg-7 text-center text-lg-start">
            <h1 class="display-4 fw-bold lh-1 mb-3">亚洲最大交友平台h1>
            <p class="col-lg-10 fs-4">Bootstrap是Twitter推出的一个用于前端开发的开源工具包。它由Twitter的设计师Mark
                Otto和Jacob Thornton合作开发,是一个CSS/HTML框架。目前,Bootstrap最新版本为5.0p>
        div>
        <div class="col-md-10 mx-auto col-lg-5">
            <form class="p-4 p-md-5 border rounded-3 bg-light" method="post">
                <div class="form-floating mb-3">
                    <input type="text" class="form-control" id="floatingInput" placeholder="[email protected]" name="username">
                    <label for="floatingInput">用户名label>
                div>
                <div class="form-floating mb-3">
                    <input type="password" class="form-control" id="floatingPassword" placeholder="Password" name="password">
                    <label for="floatingPassword">密码label>
                div>
                <div class="checkbox mb-3">
                    <label>
                        <input type="checkbox" value="remember-me"> 记住密码
                    label>
                div>
                <button class="w-100 btn btn-lg btn-primary" type="submit">登录button>
                <hr class="my-4">
                <small class="text-muted">{{error}}small>
            form>
        div>
    div>
div>
body>
html>
index.html
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js">script>
    <title>Titletitle>
head>
<body>

<div class="container">

    
    <div class="sticky-top">
        <header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
            <a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
                <svg class="bi me-2" width="40" height="32">
                    <use xlink:href="#bootstrap">use>
                svg>
                <span class="fs-4">交友平台span>
            a>

            <ul class="nav nav-pills">
                <li class="nav-item"><a href="#" class="nav-link active" aria-current="page">首页a>li>
                <li class="nav-item"><a href="#" class="nav-link">女生a>li>
                <li class="nav-item"><a href="#" class="nav-link">男生a>li>
                <li class="nav-item"><a href="#" class="nav-link">国产a>li>
                <li class="nav-item"><a href="#" class="nav-link">欧美a>li>
            ul>
        header>
    div>
    
    <div>
        <div class="bd-example-snippet bd-code-snippet">
            <div class="bd-example">
                <div id="carouselExampleCaptions" class="carousel slide" data-bs-ride="carousel">
                    <div class="carousel-indicators">
                        <button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="0" class=""
                                aria-label="Slide 1">button>
                        <button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="1"
                                aria-label="Slide 2" class="active" aria-current="true">button>
                        <button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="2"
                                aria-label="Slide 3" class="">button>
                    div>
                    <div class="carousel-inner">
                        <div class="carousel-item">
                            <img src="https://img.zcool.cn/community/[email protected]" alt=""
                                 width="100%" height="300">
                            <div class="carousel-caption d-none d-md-block">
                                <h5>激情绿荫h5>
                                <p>Some representative placeholder content for the first slide.p>
                            div>
                        div>
                        <div class="carousel-item active">
                            <img src="https://img2.baidu.com/it/u=2951612437,4135887500&fm=253&fmt=auto&app=138&f=JPEG"
                                 alt="" width="100%" height="300">
                            <div class="carousel-caption d-none d-md-block">
                                <h5>品牌雨伞h5>
                                <p>Some representative placeholder content for the second slide.p>
                            div>
                        div>
                        <div class="carousel-item">
                            <img src="https://img1.baidu.com/it/u=1417689082,3333220267&fm=253&fmt=auto&app=138&f=JPEG"
                                 alt="" width="100%" height="300">
                            <div class="carousel-caption d-none d-md-block">
                                <h5>家装节h5>
                                <p>Some representative placeholder content for the third slide.p>
                            div>
                        div>
                    div>
                    <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleCaptions"
                            data-bs-slide="prev">
                        <span class="carousel-control-prev-icon" aria-hidden="true">span>
                        <span class="visually-hidden">Previousspan>
                    button>
                    <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleCaptions"
                            data-bs-slide="next">
                        <span class="carousel-control-next-icon" aria-hidden="true">span>
                        <span class="visually-hidden">Nextspan>
                    button>
                div>
            div>
        div>

    div>

    
    <div class="row row-cols-md-2" style="padding: 10px">
        {% for k,v in user_dict.items() %}
        <div class="card">
            <div class="row " style="padding: 10px">
                <img src="{{v.get('img')}}" alt="" class="col-md-4">
                <div class="col-md-8">
                    <div class="card-body">
                        <h5 class="card-title">{{v['name']}}h5>
                        <p class="card-text">{{v.text}}p>
                        <p class="card-text">
                            <a href="/detail/{{k}}" class="btn btn-danger">查看详细a>
                        p>
                    div>
                div>

            div>

        div>
        {%endfor%}
    div>
    
    <div class="bd-example" style="margin-top: 30px">
        <table class="table table-hover table-striped table-bordered">
            <thead>
            <tr class="table-danger">
                <th colspan="3" class="text-center">更多交友th>
            tr>
            thead>
            <tbody>
            <tr class="table-success">
                <th>杨幂th>
                <td>td>
                <td>33td>
            tr>
            <tr class="table-warning">
                <th scope="row">刘亦菲th>
                <td>未知td>
                <td>40td>
            tr>
            <tr class="table-success">
                <th scope="row">彭于晏th>
                <td>td>
                <td>23td>
            tr>
            <tr class="table-warning">
                <th scope="row">陈奕迅th>
                <td>td>
                <td>44td>
            tr>
            <tr class="table-success">
                <th scope="row">薛之谦th>
                <td>td>
                <td>36td>
            tr>
            <tr class="table-warning">
                <th>李清照th>
                <td>td>
                <td>未知td>
            tr>

            tbody>
        table>
    div>
    
    <div class="d-flex justify-content-center">
        <ul class="pagination pagination-lg">
            <li class="page-item">
                <a class="page-link" href="#" aria-label="Previous">
                    <span aria-hidden="true">«span>
                a>
            li>
            <li class="page-item"><a class="page-link" href="#">1a>li>
            <li class="page-item"><a class="page-link" href="#">2a>li>
            <li class="page-item"><a class="page-link" href="#">3a>li>
            <li class="page-item"><a class="page-link" href="#">4a>li>
            <li class="page-item"><a class="page-link" href="#">5a>li>
            <li class="page-item"><a class="page-link" href="#">6a>li>
            <li class="page-item">
                <a class="page-link" href="#" aria-label="Next">
                    <span aria-hidden="true">»span>
                a>
            li>
        ul>
    div>

    
    <div>
        <footer class="py-3 my-4">
            <ul class="nav justify-content-center border-bottom pb-3 mb-3">
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">首页a>li>
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">特性a>li>
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">联系我们a>li>
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">资料获取a>li>
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">关于a>li>
            ul>
            <p class="text-center text-muted">Copyright © 1998 - 2029 liuqingzheng. All Rights Reserved. p>
        footer>
    div>
div>
body>
html>
detail.html
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js">script>
    <title>Titletitle>

head>
<body>
<div class="container">


    <div class="sticky-top">
        <header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
            <a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
                <svg class="bi me-2" width="40" height="32">
                    <use xlink:href="#bootstrap">use>
                svg>
                <span class="fs-4">交友平台span>
            a>

            <ul class="nav nav-pills">
                <li class="nav-item"><a href="#" class="nav-link active" aria-current="page">首页a>li>
                <li class="nav-item"><a href="#" class="nav-link">女生a>li>
                <li class="nav-item"><a href="#" class="nav-link">男生a>li>
                <li class="nav-item"><a href="#" class="nav-link">国产a>li>
                <li class="nav-item"><a href="#" class="nav-link">欧美a>li>
            ul>
        header>
    div>

    <div class="position-relative overflow-hidden p-3 p-md-5 m-md-3 text-center bg-light">
        <div class="col-md-5 p-lg-5 mx-auto my-5">
            <h1 class="display-4 fw-normal">{{user.name}}h1>
            <img src="{{user.img}}" alt=""
                 width="300px" height="300px" style="margin: 20px">

            <p class="lead fw-normal">{{user.text}}p>
            <a class="btn btn-outline-secondary" href="#">收藏a>
        div>
        <div class="product-device shadow-sm d-none d-md-block">div>
        <div class="product-device product-device-2 shadow-sm d-none d-md-block">div>
    div>
    <div>
        <footer class="py-3 my-4">
            <ul class="nav justify-content-center border-bottom pb-3 mb-3">
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">首页a>li>
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">特性a>li>
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">联系我们a>li>
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">资料获取a>li>
                <li class="nav-item"><a href="#" class="nav-link px-2 text-muted">关于a>li>
            ul>
            <p class="text-center text-muted">Copyright © 1998 - 2029 liuqingzheng. All Rights Reserved. p>
        footer>
    div>

div>
body>
html>

配置文件

django 中有配置文件 ⇢ \dashrightarrow settings.py ⇢ \dashrightarrow 学了多套配置文件

flask配置使用方式

  1. 方式一:直接在app中修改,只能改以下两个

    app.debug=True
    app.secret_key='asdfasdf'
    
  2. 使用py文件方式 ⇢ \dashrightarrow 跟django一样

    app.config.from_pyfile('./settings.py')
    # print(app.config)  
    # 就是所有配置信息---》就是django 的 from django.conf import settings
    # print(app.config.get("DEBUG"))
    # print(app.config.get("MYSQL_HOST"))
    
  3. 类的方式 ⇢ \dashrightarrow 以后写出多个类,上线和测试完全分开

    app.config.from_object('settings.ProductionConfig')
    # app.config.from_object('settings.DevelopmentConfig')
    # print(app.config.get('DEBUG'))
    # print(app.debug)
    # print(app.debug is app.config.get('DEBUG'))
    
  4. 其他 ⇢ \dashrightarrow 了解

    # 环境变量的值为python文件名称名称,内部调用from_pyfile方法
    app.config.from_envvar("环境变量名称")
    
    # app.config.from_json("json文件名称")
    # JSON文件名称,必须是json格式,因为内部会执行json.loads
    
    # app.config.from_mapping({'DEBUG': True})
    
  5. 配置中心 ⇢ \dashrightarrow apollo和nacos区别

    app.config.from_mapping(config_data)
    

内置配置

{
    'DEBUG':                                get_debug_flag(default=False),  是否开启Debug模式
    'TESTING':                              False,                          是否开启测试模式
    'PROPAGATE_EXCEPTIONS':                 None,                          
    'PRESERVE_CONTEXT_ON_EXCEPTION':        None,
    'SECRET_KEY':                           None,
    'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
    'USE_X_SENDFILE':                       False,
    'LOGGER_NAME':                          None,
    'LOGGER_HANDLER_POLICY':               'always',
    'SERVER_NAME':                          None,
    'APPLICATION_ROOT':                     None,
    'SESSION_COOKIE_NAME':                  'session',
    'SESSION_COOKIE_DOMAIN':                None,
    'SESSION_COOKIE_PATH':                  None,
    'SESSION_COOKIE_HTTPONLY':              True,
    'SESSION_COOKIE_SECURE':                False,
    'SESSION_REFRESH_EACH_REQUEST':         True,
    'MAX_CONTENT_LENGTH':                   None,
    'SEND_FILE_MAX_AGE_DEFAULT':            timedelta(hours=12),
    'TRAP_BAD_REQUEST_ERRORS':              False,
    'TRAP_HTTP_EXCEPTIONS':                 False,
    'EXPLAIN_TEMPLATE_LOADING':             False,
    'PREFERRED_URL_SCHEME':                 'http',
    'JSON_AS_ASCII':                        True,
    'JSON_SORT_KEYS':                       True,
    'JSONIFY_PRETTYPRINT_REGULAR':          True,
    'JSONIFY_MIMETYPE':                     'application/json',
    'TEMPLATES_AUTO_RELOAD':                None,
    }

路由系统

  1. flask 路由是基于装饰器的

    • rule:路径,不能写正则
    • methods=[‘GET’,'POST] :允许的请求方式
    • endpoint: 当前路由的别名—》反向解析用
  2. 转换器:

    类型 作用
    string (default) 任意字符串类型,不能带 /
    int 接收正整数
    float accepts positive floating point values
    path 带 / 的string
    uuid accepts UUID strings
  3. 其他写法
    @app.route + methods 不写methods 默认只有get

    • @app.get
    • @app.post
  4. 路由系统本质

    • 装饰器 ⇢ \dashrightarrow 本质是self.add_url_rule(rule, endpoint, f, **options)
    • self是 Flask(__name__) app对象
    • 自己注册路由,不使用装饰器
      app.add_url_rule('/', view_func=index)
      app.add_url_rule('/home', view_func=home)
      
  5. 其他参数:
    add_url_rule 本质就是在研究app.route 除了view_func之外的所有参数

    1. rule,URL规则
    2. view_func,视图函数名称
    3. defaults = None,默认值, 当URL中无参数,函数需要参数时,使用defaults = {‘k’: ‘v’} 为函数提供参数
    4. endpoint = None,名称,用于反向生成URL,即: url_for(‘名称’)
    5. methods = None, 允许的请求方式,如:[“GET”, “POST”]
    6. strict_slashes = None ,对URL最后的 / 符号是否严格要求
    7. redirect_to = None,重定向到指定地址

你可能感兴趣的:(flask,flask,python,后端)