flask综合案例-蓝图+列表的增删改查+模板继承

flask-Blueprint蓝图

通俗解释:
蓝图就是把所有的路由都分解成一块一块的,再把这些块和app联系,怎么联系?→(在view中定义一个蓝图,蓝图其实就是原来所用的app,只不过是换了一个名字,定义完了之后,还要在__init__中注册,相当于通上电。然后就可以在view中写各种动作,即各种路由,这些动作与以前相比是基本不变的)
其实app的启动就像是一个插排,所以为了防止代码冗余杂乱,需要把app的启动放到一个python包里。
在这里插入图片描述
本篇文章实现的功能是:利用蓝图,把用户有关的用户中心、注册界面、登录界面、更新界面和退出界面展示出来。其中注册界面中可以删除和修改,并能显示出当前所注册的人数。页面的装饰部分用到模板继承

流程说明:新建项目后,新建一个app包,自动会生成一个__init__文件。
1.在app包中,分别新建goods、order、user这三个包,代表着不同功能。在templates文件夹中也分别创建goods、order、user这三个文件夹,用来存放各自的html。(本例中只简单实现了有关user的功能,所以templates中创建了user)
在这里插入图片描述

2.在__init__这个文件里定义一个函数

from flask import Flask

import settings  # 导入配置文件
from app.user.app10_23_view import user_bp


def create_app():
    app = Flask(__name__,template_folder='../templates',static_folder='../static')
    app.config.from_object(settings) # 加载配置
    app.register_blueprint(user_bp) # 搭建桥梁!!将蓝图对象绑定到app上 # 注册蓝图到app上  user_bp是对象   注册蓝图到app上是很关键的一步!!!
    return app

其中 template_folder=‘…/templates’,static_folder=‘…/static’ 这样声明是因为:app包中的__init__和templates中的模板不是在同一级。解决方法可以是把templates和static等文件拖进app包里;
也可以像上面这样,在创建app的时候,声明一下,…/的意思是在上一级目录的某某文件夹中。

3.在app10_23中调用__init__中定义的函数

from flask import Flask

from app import create_app  # 从包里导入这个函数

app = create_app() # 调用这个函数并得到返回值

if __name__ == '__main__':
    app.run()

4.和用户有关的操作,会涉及到列表的增删改查。所以先在app包下的user包内创建一个model.py,在model.py中定义一个user类。

class User: # 定义一个用户的类
    def __init__(self,username,password,phone=None): # 包括用户名、密码和手机号
        self.username = username
        self.password = password
        self.phone = phone

    def __str__(self):
        return self.username

5.在app包中的user包中,新建app10_23_view.py,专门用来写视图的。

from flask import Blueprint, url_for, render_template, request, redirect

from app.user.model import User  # 导入在model.py中定义的user类

user_bp = Blueprint('user', __name__)  # bp是Blueprint的缩写,'user'是给蓝图起的名字!(这个名字很重要,后面反向解析路由的时候会用到)

users = []   # 列表保存的是一个一个的用户对象


@user_bp.route('/')  # 在蓝图上注册路由
def user_center():   # 用户中心
    print(url_for('user.register'))  # 反向解析,用蓝图之后,一定要加上蓝图的名字再使用反向解析(一开始我没有加user. ,就会报错)
    return render_template('user/app10_23_show.html', users=users) #  render_template()是页面的渲染。此句代码会通过 render_template去找到user目录下的app10_23_show.html来装饰页面。


@user_bp.route('/register', methods=['GET', 'POST'])  # 涉及到表单,必须注意methods要加上post这种方法!   # 这是注册
def register():
    if request.method == 'POST':  # 如果就要往后台放数据,提交方法是post
        # 获取post提交的数据(用户名、密码、确认密码和电话号)
        username = request.form.get('username')
        password = request.form.get('password')
        repassword = request.form.get('repassword')
        phone = request.form.get('phone')
        if password == repassword:  # 判断两次输入的密码是否一致
            for user in users:    # 用户名唯一的判断
                if user.username == username:
                    return render_template('user/app10_23_register.html', msg='用户名已存在')    # 如果重名了,就返回一个 msg='用户名已存在'        
            user = User(username, password, phone)    # 创建user对象           
            users.append(user)    # 添加到用户列表 
        return redirect('/')  # 重定向到主页

    return render_template('user/app10_23_register.html') # 提交完数据之后,再进入app10_23_register.html的渲染界面


@user_bp.route('/login', methods=['GET', 'POST'])  # 涉及到表单,必须注意methods
def login():
    return '用户登录'


@user_bp.route('/del')  # 删除主要是分为三步
def del_user():
    # 获取你传递的username
    username = request.args.get('username')
    # 根据username找到列表中的user对象
    for user in users:
        if user.username == username:
            # 删除user
            users.remove(user)
            return redirect('/')  # 重定向到首页
        else:  
            return '删除失败!'


@user_bp.route('/update', methods=['GET', 'POST'], endpoint='update') # 更新,涉及到数据提交到后台,所以method需要加上post;enpoint是相当于给这个路由起个名字,在url_for()路径反向解析时很方便。
def update_user():
    if request.method == 'POST':
        realname = request.form.get('realname')
        username = request.form.get('username')
        password = request.form.get('password')
        phone = request.form.get('phone')
        for user in users:
            if user.username == realname:
                user.username = username
                user.phone = phone
                return '更改成功!'

    else:  # 也就是get请求
        username = request.args.get('username')
        for user in users:
            if user.username == username:
                return render_template('user/app10_23_update.html', user=user)


@user_bp.route('/longout', methods=['GET', 'POST'])  # 涉及到表单,必须注意methods
def logout():
    return '用户退出'

6.在view.py中涉及到的三个html分别是:app10_23_show.html、app10_23_register.html、app10_23_update.html。分别完成这三个html的代码部分:
(1)app10_23_show.html.在这个html中涉及到模板继承,也就是继承了app10_23_base.html,先给出base.py的代码:

<!DOCTYPE html>  # base.py中的代码是固定装饰的基本框架,其他需要改动的部分去{%block...%}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {% block title %}  用户中心 {% endblock %}{#因为title是变化的,所以给它预留了一个block坑#}
    </title>

    <style>
        #head{
            height:50px;
            background: bisque;
        }

        #head ul {
            list-style: none; {#不让它的前边显示那个圆点#}
            height: 50px;
        }

        #head ul li{
            float: left;
            width: 100px;
            text-align: center;{#字体居中#}
            font-size: 18px;
            height: 50px;
            line-height:50px;
        }

        #middle{
            height:600px;
            background-color: #86989B;
        }
        #foot{
            height: 50px;
            line-height: 50px;
            background-color:darkred;
        }
    </style>
{% block mycss %}  {% endblock %}  {#给装饰部分预留位置,注意是位置#}
</head>

<body>
    <div id ="head">
        <ul>
            <li><a href="">首页</a></li>
            <li><a href="">秒杀</a></li>
            <li><a href="">超市</a></li>
            <li><a href="">图书</a></li>
            <li><a href="">会员</a></li>
       </ul>
    </div>

    <div id="middle">
        {% block middle %}{#给中间的样式部分预留坑位#}

        {% endblock %}
    </div>

    <div id="foot">

    </div>
{% block myjs %}
{% endblock %}  {#给脚本留出位置#}
</body>
</html>

以下是app10_23_show.html的代码部分:

{% extends 'app10_23_base.html' %} {#意思是继承app10_23_base.html   block和endblock是不区分先后顺序的#}
{% block middle %}
    <h1>用户信息</h1>
    <span>当前用户的人数是:{{ users | length }}</span>
    <table border="1" cellspacing="0" width="60%" >
      {% for user in users %}
         <tr>
             <td>{{ loop.index }}</td>
             <td>{{ user.username }}</td>
             <td>{{ user.passwoed }}</td>
             <td>{{ user.phone }}</td>
             <td><a href="javascript:;" onclick="update('{{ user.username }}')">修改</a>
                 <a href="javascript:;" onclick="del('{{ user.username }}')">删除</a></td>
         </tr>
      {% endfor %}
    </table>
{% endblock %}


{% block myjs %}
    <script>
    //定义删除的函数
      function del(username){
          // console.log(username)
          //location 地址栏对象
          location.href = '/del?username='+username {#点谁就要把谁的名字拼接到后边来#}
      }

      //定义修改的函数
      function update(username){
          // console.log(username)
          //location 地址栏对象
          location.href = '/update?username='+username {#点谁就要把谁的名字拼接到后边来#}
      }
    </script>
{% endblock %}

(2)app10_23_register.html的代码部分:

{% extends 'app10_23_base.html' %} {#意思是继承app10_23_base.html   blockhe endblock是不区分先后顺序的#}
{% block title %}
   用户注册
{% endblock %}

{% block middle %} {#middle的样式#}
    <p style="color:red">{{ msg }}</p>
    <form action="{{ url_for('user.register') }}" method="post">  {#这个地方写错了,一开始写的’user.app10_23_register‘,重定向的时候应该写路径,而不是文件名#}
        <p><input type="text" name="username" placeholder="用户名"></p>
        <p><input type="password" name="password" placeholder="密码"></p>
        <p><input type="password" name="repassword" placeholder="确认密码"></p>
        <p><input type="number" name="phone" placeholder="手机号码"></p>
        <p><input type="submit" value=用户注册></p>
    </form>
{% endblock %}

(3)app10_23_update.html的代码部分:

{% extends 'app10_23_base.html' %}
{% block title %}
用户信息修改
{% endblock %}
{% block middle %}
    <h1>用户信息更新</h1>
    <form action="{{ url_for('user.update') }}" method="post">
        <p><input type="hidden" name="realname" value="{{ user.username }}"></p>
        <p><input type="text" name="username" placeholder="用户名" value="{{ user.username }}"></p>
        <p><input type="password" name="password" placeholder="密码" value="{{ user.password }}" disabled></p>
        <p><input type="number" name="phone" placeholder="手机号码" value="{{ user.phone }}"></p>
        <p><input type="submit" value=用户注册"></p>
    </form>
{% endblock %}

7.最后要补上setting.py配置文件

# 配置文件
ENV='development'
DEBUG=True
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的研一小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值