【Python】基于flaskMVT架构与session实现博客前台登录登出功能

目录

一、MVT说明

1.Model层

2.View层

3.Template层

二、功能说明

三、代码框架展示

四、具体代码实现

models.py

登录界面前端代码

博客界面前端代码(profile.html)

main.py


一、MVT说明

MVT架构是Model-View-Template的缩写,是Django框架的架构。Flask框架本身并没有强制使用MVT架构,但是我们可以通过一些方式来实现类似MVT架构的结构。

以下是一个简单的在Flask中实现MVT的示例:

1.Model层

在Flask中,我们可以使用SQLAlchemy作为ORM框架,用于操作数据库。我们可以在app目录下创建一个models.py文件,并定义我们需要的数据模型类。例如:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    password = db.Column(db.String(128), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

2.View层

在Flask中,我们可以使用Blueprints来组织我们的视图函数。我们可以在app目录下创建一个views.py文件,并创建一个蓝图对象,用于定义我们的视图函数。例如:

from flask import Blueprint

bp = Blueprint('main', __name__)

@bp.route('/')
def index():
    return 'Hello, World!'

3.Template层

在Flask中,我们可以使用Jinja2作为模板引擎,用于渲染HTML页面。我们可以在app目录下创建一个templates目录,并在其中创建我们的HTML模板文件。例如:

<!doctype html>
<html>
  <head>
    <title>{{ title }}</title>
  </head>
  <body>
    <h1>Hello, {{ username }}!</h1>
  </body>
</html>

然后,在我们的视图函数中使用render_template函数来渲染模板文件。例如:

from flask import render_template

@bp.route('/hello/<username>')
def hello(username):
    return render_template('hello.html', title='Flask MVT Demo', username=username)

以上就是一个简单的在Flask中实现MVT的示例。通过这种方式,我们可以将应用逻辑、数据库操作和HTML页面渲染分别放在不同的层次中,使代码更加清晰和易于维护。

二、功能说明

展示了登录界面和博客界面

实现基于初始界面多路由跳转

通过jinja2模板引擎完成html页面的数据替换

使用SQLAlchemy完成数据操作

使用request获取用户提交的参数

使用session实现权限验证,登录登出

三、代码框架展示

四、具体代码实现

models.py

from sqlalchemy import create_engine
from sqlalchemy import Column,String,Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

#链接是需要指定要用到的MySQL数据库
engine=create_engine('mysql+pymysql://root:root@localhost:3306/flask_1?charset=utf8')
Base=declarative_base() #生成SQLORM基类

class User(Base):
    #对应MySQL中数据表的名字
    __tablename__='user'
    #创建字段
    id=Column(Integer,primary_key=True)
    user_id=Column(String(50),nullable=False)
    username=Column(String(50),nullable=False)
    head_img=Column(String(200))
    short_description=Column(String(300))

登录界面前端代码

简单的Login Form登录页html模板

博客界面前端代码(profile.html)

<!DOCTYPE html>
<!--[if IE 8]> <html lang="en" class="ie8"> <![endif]-->
<!--[if IE 9]> <html lang="en" class="ie9"> <![endif]-->
<!--[if !IE]><!--> <html lang="en"> <!--<![endif]-->
<head>
<title>Home</title>
<!-- Meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="">
<link href='https://fonts.googleapis.com/css?family=Roboto:400,500,400italic,300italic,300,500italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'>
<!-- Global CSS -->
<link rel="stylesheet" href="assets/plugins/bootstrap/css/bootstrap.min.css">
<!-- Plugins CSS -->
<link rel="stylesheet" href="assets/plugins/font-awesome/css/font-awesome.css">

<!-- Theme CSS -->
<link id="theme-style" rel="stylesheet" href="assets/css/styles.css">

</head>

<body>

<header class="header">

    <div class="intro">
         <div class="container text-right">
             <a href={{url_for('logout')}}>退出登录</a>
        </div><!--//container-->
        <div class="container text-center">
            <h1 class="name">{{user.username}}</h1>
            <div class="title">Full Stack Developer</div>
            <div class="profile">
                <p>{{user.short_description}}</p>
            </div><!--//profile-->
        </div><!--//container-->
    </div><!--//intro-->

    <div class="contact-info">
        <div class="container text-center">
            <ul class="list-inline">
                <li class="email"><i class="fa fa-envelope"></i><a href="mailto:someone@example.com">james.doe@website.com</a></li>
                <li><i class="fa fa-phone"></i> <a href="tel: 0123456789">0123 456 7890</a></li>
                <li class="website"><i class="fa fa-globe"></i><a href="#" target="_blank">portfoliosite.com</a></li>
            </ul>
        </div><!--//container-->
    </div><!--//contact-info-->


</header><!--//header-->

<div class="wrapper container">
    <section id="contact-section" class="contact-section section">
        <h2 class="section-title">Get in Touch</h2>
        <div class="intro">
            <img class="profile-image" src="assets/images/profile-image.png" alt="">
            <div class="dialog">
                <p>I'm currently taking on freelance work. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.</p>
                <p><strong>I can help with the following:</strong></p>
                <ul class="list-unstyled service-list">
                    <li><i class="fa fa-check" aria-hidden="true"></i> App development with ReactJS</li>
                    <li><i class="fa fa-check" aria-hidden="true"></i> Front-end development with AngularJS</li>
                    <li><i class="fa fa-check" aria-hidden="true"></i> Back-end development with Django/Python</li>
                    <li><i class="fa fa-check" aria-hidden="true"></i> UI development</li>
                    <li><i class="fa fa-check" aria-hidden="true"></i> UX prototyping</li>
                </ul>
                <p>Drop me a line at <a href="mailto:someone@example.com">james.doe@website.com</a> or call me at <a href="tel:01234567890">0123 456 7890</a></p>
                <ul class="social list-inline">
                    <li><a href="#"><i class="fa fa-linkedin" aria-hidden="true"></i></a></li>
                    <li><a href="#"><i class="fa fa-twitter" aria-hidden="true"></i></a></li>
                    <li><a href="#"><i class="fa fa-google-plus" aria-hidden="true"></i></a></li>
                    <li><a href="#"><i class="fa fa-github-alt" aria-hidden="true"></i></a></li>
                    <li><a href="#"><i class="fa fa-skype" aria-hidden="true"></i></a></li>
                </ul><!--//social-->
            </div><!--//diaplog-->
        </div><!--//intro-->

    </section><!--//section-->

</div><!--//wrapper-->

</body>
</html>

main.py

#1.导入flask
from flask import Flask, redirect, url_for, request, make_response,session
from flask import render_template

from models.models import *


#2.用flask创建应用对象
app=Flask(__name__)
app.config['SECRET_KEY']='Z3r4y'


#3. 用应用对象.route("/index.html")对函数进行装饰,这个函数中写业务逻辑
@app.route("/")
@app.route("/index")
def index():
    return redirect('profile')

@app.route("/profile")    #当调用profile的时候,就相当于profile(user_id=xxx)
#当调用这个函数的时候,意味着用户要访问简历页面,至于是否可以访问,则要检查用户请求中的cookie,如果有,那么就认为可以访问,否则禁止访问
def profile():  #如果想调用profile成功,那么只有user_id这个位置的是纯数字的时候,才可以调用
    # 如果一个函数它是一个普通的功能的话,它一般包括2个功能:
    #1.业务方面的数据处理(对变量user_id的使用,例如查询数据库等)
    #2.模板的替换(对应profile.html的获取以及字符的替换)
    # with open('profile.html',encoding='utf-8') as f:
    #     content=f.read().replace("xxxxxxxx",str(user_id))
    #     return content

    # conn=pymysql.connect(host='localhost', user='root', password='root', database='flask_1', charset='utf8')
    # csl=conn.cursor()
    # params=[user_id]
    # csl.execute('select * from user where user_id=%s',params)
    # result=csl.fetchone()
    # print(result)
    # csl.close()
    # conn.close()
    # login_flag=request.cookies.get('login_flag')
    # user_id=request.cookies.get('user_id')  #从cookie中提取用户的id
    login_flag=session.get('login_flag')
    user_id=session.get('user_id')
    if not (login_flag and login_flag=="success" and user_id):
        return redirect(url_for('login'))

    db_session=sessionmaker(bind=engine)() #生成链接数据库的实例
    user_ret=db_session.query(User).filter(User.user_id==user_id).one()    #将从cookie中查询出来的user_id道数据库中查询这个用户
    # print(user_ret)
    db_session.close()
    # 使用模板(jinja2模板引擎),可以对html的数据处理进行了封装
    # return render_template("profile.html",user_name="Z3r4y")
    # return render_template("profile.html",user_name=result[2],short_desc=result[4])  #注意:它会默认到templates文件夹中去找 profile.html
    return render_template("profile.html",user=user_ret)

@app.route('/login')
def login():
    #判断用户名以及密码或者还有验证码是否成立,如果成立则告知浏览器用户登录成功,且让浏览器自动跳转主页
    # print(request.args)
    if request.args:
        user_name=request.args.get('Username')
        password=request.args.get('Password')
        #1.业务处理
        print("用户名是",user_name)
        print("密码是",password)
        db_session = sessionmaker(bind=engine)()  # 生成链接数据库的实例
        user_ret = db_session.query(User).filter(User.username == user_name).first()
        db_session.close()
        print(user_ret)
        if user_ret:
            # response=make_response("<h1>登陆成功</h1>")
            response=make_response(redirect(url_for('index')))
            # response.set_cookie("user_id",user_ret.user_id)
            # response.set_cookie("login_flag","success")
            session['login_flag']="success"
            session['user_id']=user_ret.user_id
            return response
        else:
            return "<h1>登陆失败</h1>"
        # return redirect('/index')
        # return redirect(url_for("profile",user_id=2))   #帮助我们动态地生成与路由函数关联的URL
    else:
        return render_template('login.html')

@app.route('/logout')
def logout():
    # #1.清理cookie
    # response=make_response(redirect(url_for('index')))
    # response.delete_cookie('login_flag')
    # response.delete_cookie('user_id')
    #1.清理session
    session.clear()
    # 2.跳转到主页
    return redirect(url_for('index'))

@app.route('/demo')
def demo():
    return "状态码",404


#4.应用程序.run()
app.run(debug=True,port=1337,host="0.0.0.0")     #开启调试模式,意味着如果有代码的改动,flask会自动重启服务器
# app.run()
# print(app.url_map)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/266793.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VS(Visual Studio)更改文件编码

vs默认编码是GB2312,更改为UTF-8 工具->自定义

Tomcat与Netty比较

Tomcat介绍Tomcat支持的协议Tomcat的优缺点Netty介绍Netty支持的协议Netty的优点和缺点Tomcat和Netty的区别Tomcat和Netty的应用场Tomcat和Netty来处理大规模并发连接的优化Tomcat与Netty的网络模型的区别Tomcat与Netty架构设计拓展 Tomcat介绍 Tomcat是一个免费的、开放源代码…

nodejs+vue+ElementUi摄影作品图片分享工作室管理系统

第1周 2.21&#xff5e;2.27 查阅资料&#xff0c;学习vscode开发平台和vue框架技术 第2周 2.28&#xff5e;3.6 对软件功能需求进行分析, 软件功能模块划分及软件界面设计 第3周 3.7&#xff5e;3.13 撰写并提交毕业设计开题报告、英文资料翻译 第4周 3.14&#xff5…

深度学习中的池化

1 深度学习池化概述 1.1 什么是池化 池化层是卷积神经网络中常用的一个组件&#xff0c;池化层经常用在卷积层后边&#xff0c;通过池化来降低卷积层输出的特征向量&#xff0c;避免出现过拟合的情况。池化的基本思想就是对不同位置的特征进行聚合统计。池化层主要是模仿人的…

【docker笔记】docker理论及安装

前言 本笔记来源于尚硅谷docker教学视频 视频地址&#xff1a;https://www.bilibili.com/video/BV1gr4y1U7CY/?spm_id_from333.337.search-card.all.click 纯手打笔记&#xff0c;来之不易&#xff0c;感谢支持~ Docker简介 docker为什么会出现 想象一下&#xff1a;一个应用…

Web前端-JavaScript(Dom基础)

文章目录 1.1 DOM 介绍1.1.1 DOM简介1.1.2 DOM树 1.2. 获取元素1.2.1 根据ID获取元素1.2.2 根据标签名获取元素1.2.3 其它方式获取元素1.2.4 获取特殊元素 1.3 事件基础1.3.1 事件概述1.3.2 事件三要素1.3.3 执行事件步骤1.3.4 鼠标事件 1.4 操作元素1.4.1 操作元素内容1.4.2 属…

Java小案例-MusiQ音乐网站

目录 前言 项目功能 技术栈 后端 前端 开发环境 项目展示 前台-首页-展示 前台-首页-代码 前台-歌单-展示 前台-歌单-代码 前台-歌手-展示 前台-歌手-代码 前台-其他页面展示 后台-登录-展示 后台-登录-代码 后台-首页-展示 首台-首页-代码 后台-其他页面-展…

PyQt6 QColorDialog颜色对话框控件

锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计50条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话版…

基于Qt之QChart 图表(优美的曲线图案例)

## 项目演示 平台:ubuntu18.04 Qt版本:QT5.14.2 源码位置GitCode:https://gitcode.com/m0_45463480/QCharts/tree/main ## QChart 图表 自从 Qt 发布以来,给跨平台的用户带来很多便利。在 Qt5.7 之前,Qt 在开源社区版本里没有 Qt Charts(自带的绘图组件库)。这使得像…

SpringBoot的日志管理

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

Kubernetes api-server源码阅读2(Debug Kubernetes篇)

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Kubernetes api-server源码阅读 系列第二篇&#xff0c;主要讲述如何实现 kubernetes api-server 的 debug 参考b站视频地址&#xff1a;Kubernetes源码开发之旅二 1.本篇章任务 Go-Delve&#xff1a;go语言的…

INFINI Gateway 如何防止大跨度查询

背景 业务每天生成一个日期后缀的索引&#xff0c;写入当日数据。 业务查询有时会查询好多天的数据&#xff0c;导致负载告警。 现在想对查询进行限制–只允许查询一天的数据&#xff08;不限定是哪天&#xff09;&#xff0c;如果想查询多天的数据就走申请。 技术分析 在每…

排序算法——桶排序

把数据放进若干个桶&#xff0c;然后在桶里用其他排序&#xff0c;近乎分治思想。从数值的低位到高位依次排序&#xff0c;有几位就排序几次。例如二位数就排两次&#xff0c;三位数就排三次&#xff0c;依次按照个十百...的顺序来排序。 第一次排序&#xff1a;50 12 …

二级指针的作用 -- 将变量从函数中带出

使用一级指针不能将变量带出 void test(int *p) {static int nub 10; /*使用static是保证函数结束, 变量依然存在, 不然即使将它带出来, 函数结束时这片内存已经被释放了就没有意义了*/p &nub; }int main(void) {int *p NULL;test(p);printf("%d",*p);return …

计算机网络-网络层

计算机网络-网络层 以下笔记整理为哔哩哔哩湖科大教书匠的《计算机网络微课堂》的教学视频。 链接&#xff1a;计算机网络微课堂 1. 网络层概述 1.1 网络层的主要任务是实现网络互联&#xff0c;进而实现数据包在各网络之间的传输。 1.2 要实现网络层任务&#xff0c;需要解决…

java中静态修饰符(static)的使用

static-静态 修饰属性 静态属性,也称为静态变量 类变量等 static 数据类型 属性名; 使用 静态内容独立存放在方法区 静态内容在内存中只有一份,被该类所有对象共享 普通属性所有对象在对象内容中都有一份 可以通过类名.静态属性名的方式直接访问静态属性 静态属性封装之…

Milvus数据一致性介绍及选择方法

1、Milvus 时钟机制 Milvus 通过时间戳水印来保障读链路的一致性&#xff0c;如下图所示&#xff0c;在往消息队列插入数据时&#xff0c; Milvus 不光会为这些插入记录打上时间戳&#xff0c;还会不间断地插入同步时间戳&#xff0c;以图中同步时间戳 syncTs1 为例&#xff0…

MySQL 数据库系列课程 04:MySQL Workbench的安装

Workbench 是 MySQL 官方推出的免费的强大的可视化工具&#xff0c;不熟悉命令行工具的人&#xff0c;可以安装这一款软件&#xff0c;通过编写 SQL 进行数据库中数据的增删改查操作&#xff0c;接下来我们详细说明一下 Workbench 的安装。 一、Windows安装Workbench &#x…

postgresql vacuum流程分析

概述 VACUUM是postgresql MVCC机制不可分割的组成部分。 postgresql在管理同一个元组的多个版本时&#xff0c;采取在堆表页面上从老版本到新版本放置元组的方法&#xff0c;每个元组都记录了xmax和xmin用于判断其可见性。这样的好处是&#xff08;1&#xff09;在索引键没有…

HarmonyOS - 基础组件绘制

文章目录 所有组件开发 tipsBlankTextImageTextInputButtonLoadingProgress 本文改编自&#xff1a;<HarmonyOS第一课>从简单的页面开始 https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101667360160710997 所有组件 在 macOS 上&#xff0c;组…