热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Python-Flask框架开发Web网站系列课程(三)登录功能

前言使用IDE:PyCharm操作系统:MacPython版本:3.6我的邮箱:51263921@qq.com交流群:372430835说明:本次课程github代
前言

使用IDE:PyCharm

操作系统: Mac

Python版本:3.6

我的邮箱:51263921@qq.com

交流群: 372430835

说明:

本次课程github代码在最下面。

本次课程基于上个课程的代码,如果没看过的请先传送:

使用Python-Flask框架开发Web网站系列课程(一)构建项目

使用Python-Flask框架开发Web网站系列课程(二)注册功能

 

一、登录

本次课程主要实现登录,我们按照实际开发的流程,先看到登录页面,再尝试页面传值(也就是输入账号密码)到服务端,服务端校验和鉴权,并跳转页面。

1.1 增加 backend.account.views  关于登录的代码

全路径:/myproject/backend/account/views.py

#!/usr/bin/python # -*- coding: UTF-8 -*- """ Created by liaoyangyang1 on 2018/8/22 上午9:40. """ from flask import Blueprint,request,render_template,jsonify,flash #第二课增加内容 from backend.models.UserModel import User from backend.models import db #账户的蓝图 访问http://host:port/account 这个链接的子链接,都会跳到这里 account = Blueprint('/account', __name__) #第二课增加内容 # 访问http://host:port/account/register 这个链接,就会跳到这里 @account.route('/register',methods=(["GET","POST"])) #第二课增加内容 #上面的链接,绑定的就是这个方法,我们给浏览器或者接口请求 一个json格式的返回 def register(): #第二课增加内容 if request.method == 'POST': form = request.form user = User(username=form['username'],email=form['email'],password=form['password']) db.session.add(user) db.session.commit() return jsonify(form) return render_template('/account/register.html') @account.route('/login',methods=(["GET","POST"])) def login(): #第三课内容 if request.method == "POST": return jsonify(request.form) return render_template('/account/login.html') 

1.2 增加html页面文件

全路径:/myproject/frontend/account/login.html

\n        
\n
\n

IN+

\n
\n

Welcome to IN+

\n

Perfectly designed and precisely prepared admin theme with over 50 pages with extra new web app views.\n \n

\n

Login in. To see it in action.

\n \n
\n \n
\n
\n \n
\n\n {% with messages = get_flashed_messages() %}\n {% if messages %}\n
\n {% for message in messages %}\n {{ message }}\n {% endfor %}\n
\n {% endif %}\n {% endwith %}\n\n \n\n Forgot password?\n

Do not have an account?

\n Create an account\n \n

Inspinia we app framework base on Bootstrap 3 © 2014

\n
\n
\n\n \n \n \n\n\n\n","classes":{"has":1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet"> <html> <head> <meta charset="utf-8"> <meta name="viewport" cOntent="> <title>INSPINIA | Logintitle> <link href="https://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.css" rel="stylesheet"> <link href="https://cdn.bootcss.com/font-awesome/4.3.0/css/font-awesome.css" rel="stylesheet"> <link href="https://cdn.bootcss.com/animate.css/3.5.2/animate.css" rel="stylesheet"> <link href="../static/css/style.css" rel="stylesheet"> head> <body class="gray-bg"> <div class="middle-box text-center loginscreen animated fadeInDown"> <div> <div> <h1 class="logo-name">IN+h1> div> <h3>Welcome to IN+h3> <p>Perfectly designed and precisely prepared admin theme with over 50 pages with extra new web app views. p> <p>Login in. To see it in action.p> <form class="m-t" role="form" action="/account/login" method="post"> <div class="form-group"> <input type="text" class="form-control" name="username" placeholder="Username" required=""> div> <div class="form-group"> <input type="password" class="form-control" name="password" placeholder="Password" required=""> div> {% with messages = get_flashed_messages() %} {% if messages %} <div class="alert alert-success"> {% for message in messages %} {{ message }} {% endfor %} div> {% endif %} {% endwith %} <button type="submit" class="btn btn-primary block full-width m-b">Loginbutton> <a href="#"><small>Forgot password?small>a> <p class="text-muted text-center"><small>Do not have an account?small>p> <a class="btn btn-sm btn-white btn-block" href="register.html">Create an accounta> form> <p class="m-t"> <small>Inspinia we app framework base on Bootstrap 3 © 2014small> p> div> div> <script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.js">script> <script src="https://cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.js">script> body> html>

1.3 测试一把

点击login后显示如下的话,表示成功。

{
"password": "abc123",
"username": "admin"
}

1.4 修改backend.account.view 增加鉴权代码

1.4.1 装个包    pip install Flask-Login==0.4.1

1.4.2 修改 /myproject/backend/view.py  注意修改文件的路径

#!/usr/bin/python # -*- coding: UTF-8 -*- """ Created by liaoyangyang1 on 2018/8/21 下午3:51. """ from flask_login import LoginManager #第三课新增 # Set up Flask-Login login_manager = LoginManager() #第三课新增 login_manager.session_protection = 'strong' #第三课新增 login_manager.login_view = 'account.login' #第三课新增

1.4.3 修改/myproject/backend/__init__.py

#!/usr/bin/python # -*- coding: UTF-8 -*- """ Created by liaoyangyang1 on 2018/8/21 下午2:41. """ import os from flask import Flask from config.config import config from backend.urls import register from backend.models import db #第二课增加内容 from backend.views import login_manager #第三课增加内容 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_TEMPLATE_FOLDER = os.path.join(BASE_DIR,'frontend') def create_app(): #初始化项目实例 app = Flask(__name__,template_folder=BASE_TEMPLATE_FOLDER,static_folder=os.path.join(BASE_DIR,'frontend','static')) app.secret_key = app.config['SECRET_KEY'] #导入配置项 app.config.from_object(config) # 注册路由 register(app) # 注册数据库 db.init_app(app) #第二课增加内容 #注册登录组件 login_manager.init_app(app) #第三课增加内容 # 钩子 在请求执行之前  @app.before_request def before_request(): print('hi') return app

1.4.4 修改/myproject/backend/account/views.py

这里和之前的区别是增加了鉴权的内容,判断用户名和密码是否为空,判断密码对不对。增加了登出的功能。

#!/usr/bin/python # -*- coding: UTF-8 -*- """ Created by liaoyangyang1 on 2018/8/22 上午9:40. """ from flask import Blueprint,request,render_template,jsonify,flash #第二课增加内容 from flask import redirect,url_for,current_app from backend.models.UserModel import User from backend.models import db from flask_login import login_user,login_required,logout_user #第三课增加内容 #账户的蓝图 访问http://host:port/account 这个链接的子链接,都会跳到这里 account = Blueprint('account', __name__) #第二课增加内容 # 访问http://host:port/account/register 这个链接,就会跳到这里 @account.route('/register',methods=(["GET","POST"])) #第二课增加内容 #上面的链接,绑定的就是这个方法,我们给浏览器或者接口请求 一个json格式的返回 def register(): #第二课增加内容 if request.method == 'POST': form = request.form user = User(username=form['username'],email=form['email'],password=form['password']) db.session.add(user) db.session.commit() return jsonify(form) return render_template('/account/register.html') @account.route('/login',methods=(["GET","POST"])) def login(): #第三课内容 if request.method == "POST": form = request.form #获取登录表单 user = User.query.filter_by(username=form['username']).first() #查出用户信息 if user is not None and user.password_hash is not None and user.verify_password(form['password']): #检查密码是否正确 login_user(user,True) #登录操作 flash('You are now logged in. Welcome back!', 'success') return redirect( url_for(request.args.get('next') or 'admin.index')) else: flash('Invalid email or password.', 'error') return render_template('/account/login.html') @account.route('/logout') @login_required def logout(): logout_user() flash('You have been logged out.', 'info') return redirect(url_for('admin.index'))

1.4.5 调整一下我们的/myproject/backend/models/UserModel.py

 增加了鉴权模块需要的东西,知识点可以百度flask_login的user_loader和anonymous_user

' % self.username\n\nclass AnonymousUser(AnonymousUserMixin): #第三课新增\n    def can(self, _):\n        return False\n\n    def is_admin(self):\n        return False\n\n\nlogin_manager.anonymous_user = AnonymousUser   #第三课新增\n\n\n@login_manager.user_loader  \ndef load_user(user_id): #第三课新增\n    return User.query.get(int(user_id))","classes":{"has":1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet">#!/usr/bin/python # -*- coding: UTF-8 -*- """ Created by liaoyangyang1 on 2018/8/22 下午1:50. """ from flask_login import UserMixin,AnonymousUserMixin #第二课增加内容 from werkzeug.security import check_password_hash, generate_password_hash #第二课增加内容 from backend.models import db #第二课增加内容 from backend.views import login_manager #第三课新增 class User(UserMixin, db.Model): #第二课增加内容 __tablename__ = 'users' #这是我们将来建出来的表的表名,在这里定义,下面的都是字段名和字段类型长度这些 id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True) email = db.Column(db.String(64), unique=True, index=True) password_hash = db.Column(db.String(128)) #脱敏  @property def password(self): #第二课增加内容 raise AttributeError('`password` is not a readable attribute') #加密  @password.setter def password(self, password): #第二课增加内容 self.password_hash = generate_password_hash(password) #校验密码 def verify_password(self, password): #第二课增加内容 return check_password_hash(self.password_hash, password) #查询返回的格式 def __repr__(self): #第二课增加内容 return '' % self.username class AnonymousUser(AnonymousUserMixin): #第三课新增 def can(self, _): return False def is_admin(self): return False login_manager.anonymous_user = AnonymousUser #第三课新增 @login_manager.user_loader def load_user(user_id): #第三课新增 return User.query.get(int(user_id))

1.4.6 增加前端目录和页面

先建文件夹

      全路径:/myproject/frontend/base

新增页面html文件layout.html

       /myproject/frontend/base/layout.html

内容为:

 <title>My Applicationtitle> {% with messages = get_flashed_messages() %} {% if messages %} <ul class=flashes> {% for message in messages %} <li>{{ message }}li> {% endfor %} ul> {% endif %} {% endwith %} {% block body %}{% endblock %} 

新增页面html文件index.html

    /myproject/frontend/base/index.html

Overview\n  {% if current_user.is_authenticated %}\n    

welcome ~ logout\n {% else %}\n

Do you want to log in?\n {% endif %}\n{% endblock %}\n","classes":{"has":1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="codeSnippet">{% extends "base/layout.html" %} {% block body %} <h1>Overviewh1> {% if current_user.is_authenticated %} <p>welcome ~ <a href="/account/logout">logouta> {% else %} <p>Do you want to <a href="/account/login">log in?a> {% endif %} {% endblock %}

1.4.7 新增后端文件夹和文件

在/myproject/backend/下新增文件夹  admin

       全路径: /myproject/backend/admin

在admin下新增__init__.py和views.py

      /myproject/backend/admin/__init__.py内容为空

     全路径: /myproject/backend/admin/views.py

     内容如下:

#!/usr/bin/python # -*- coding: UTF-8 -*- """ Created by liaoyangyang1 on 2018/8/23 上午11:09. """ from flask import Blueprint,render_template from backend.account.views import login_required admin = Blueprint('admin', __name__) @admin.route('/') def index(): return render_template('/base/index.html')

 

 二、测试登录

访问http://127.0.0.1:10101/admin/

显示内容为,意思就是你没登录,让你点log in:

Overview

Do you want to log in?

点击后跳转页面,到我们一开始做的登录页面,url为http://127.0.0.1:10101/account/login

输入账号密码登录,成功的话跳转回一开始的页面,但是显示内容变了:

 

Overview

welcome ~ logout

 

是不是很简单~

三、本课代码

github: https://github.com/lyy8510a/myproject/releases/tag/v3


推荐阅读
  • 本文介绍了django中视图函数的使用方法,包括如何接收Web请求并返回Web响应,以及如何处理GET请求和POST请求。同时还介绍了urls.py和views.py文件的配置方式。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
author-avatar
空白画叶子
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有