Flask项目之手机端租房网站的实战开发(八)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!
接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/86247891
目录
一丶构建一个用于验证登录状态的装饰器
1.因为这个装饰器用的地方比较多,所以就在项目中的utils目录下的commons模块中进行定义
def login_required(view_func):
"""
验证登录状态的装饰器
:param view_func: 需要装饰的视图函数
:return:
"""
def wrapper(*args, **kwargs):
pass
2.获取session中用户id
user_id = session.get("user_id")
3.根据user_id来判断用户登录状态,如果user_id不为空,说明用户已经登录,那么就执行视图函数,否则返回对应错误信息
if user_id is not None:
return view_func(*args, **kwargs)
else:
return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
4.通过flask中的g对象来保存将来在视图函数中要用的user_id
g.user_id = user_id
5.导入python标准库functools,见名知义,就是函数工具库,这个库有个wraps方法,用于作为在闭包中的内置函数的装饰器,意义就是不会改变函数使用装饰前的特性(建议再定义装饰器时,在内置函数上添加@functools.wraps()装饰器)
@functools.wraps(view_func)
def wrapper(*args, **kwargs):
二丶七牛云的使用
1.图片存储服务---七牛云
- step1 在https://portal.qiniu.com/signup 进行注册
- step2 注册成功后,添加进入对象存储
- step3 新建存储空间,如下图所示(需要实名认证审核期为三天)
创建成功后,1个月的测试使用期限
- step4 进入文档中心----》选择SDK&工具----》官方SDK----》找到Python(服务端),点击文档说明,有案列以及安装方法
- step5 查看官网提供的上传图片案列
# -*- coding: utf-8 -*-
# flake8: noqa
from qiniu import Auth, put_file, etag
import qiniu.config
#需要填写你的 Access Key 和 Secret Key
access_key = 'Access_Key'
secret_key = 'Secret_Key'
#构建鉴权对象
q = Auth(access_key, secret_key)
#要上传的空间
bucket_name = 'Bucket_Name'
#上传到七牛后保存的文件名
key = 'my-python-logo.png'
#生成上传 Token,可以指定过期时间等
token = q.upload_token(bucket_name, key, 3600)
#要上传文件的本地路径
localfile = './sync/bbb.jpg'
ret, info = put_file(token, key, localfile)
print(info)
assert ret['key'] == key
assert ret['hash'] == etag(localfile)
- step6 Access_Key以及Secret_Key在个人面板-----》密匙管理里进行查看
2.在项目utils目录下创建一个image_storage.py文件,用于我们作进一步的封装
- step1 将案列代码拷贝到该py文件中,填写access_key和secret_key,以及要上传的空间名bucket_name
- step2 不设定key上传到七牛上的文件名,即设定key变量的值为None
- step3 通过导入的qiniu库,查看qiniu/init中除了案列中import的put_file方法(通过文件名上传),还有另外一个put_data方法(通过文件二进制流上传),我们使用put_data方法,这样直接从本地通过with open read方法直接将图片读取出来的二进制数据上传到七牛
- step4 修改代码,不使用put_file方法,使用put_data方法
ret, info = put_data(token, None, localfile)
- step5 封装代码到storage方法中
- step6 通过with open read方式读取image_storage文件同路径下的1.jpg图片,调用storage方法将读取的二进制内容传给此方法
if __name__ == '__main__':
with open("./1.jpg","rb") as f:
file_data = f.read()
storage(file_data)
3.测试七牛云接口,进行图片上传
- step1 运行程序,查看打印的ret的值和info的值,状态码200就表示上传成功,hash值顾名思义使用hash转换后的值,因为程序中注释掉了key文件名,所以七牛云就将hash值当作了key值
- step2 回到七牛云上,刷新页面,进入存储空间中的内容管理,就能看到我们刚上传的图片了,这里图片名字就是程序运行结果中的hash值
- step3 浏览器中打开新的标签,将域名+/+文件名中间以/分割,拼接到一起,粘贴到标签地址栏中,回车则可以查看该我们上传的图片了
三丶上传头像后端编写
1.在api_1.0目录下创建profile.py文件,用于作个人信息逻辑编辑
2.在init文件中导入此py文件
from . import verify_code, passport, profile
3.定义视图函数以及路由规则
@api.route("/users/avatar", methods=["POST"])
def set_user_avatar():
"""
上传头像图片
:param image user_id
:return:
"""
pass
4.导入之前定义的验证登录状态的装饰器
from ihome.utils.commons import login_required
5.编写业务逻辑
- step1 获取用户id
user_id = g.user_id
- step2 获取图片
image_file = request.files.get("avatar")
- step3 判断用户是否上传图片
if image_file is None:
return jsonify(errno=RET.PARAMERR, errmsg="未上传图片")
- step4 读取图片二进制数据
image_data = image_file.read()
- step5 修改image_storage文件,当状态码为200时,返回key值,不为200时表示上传失败,返回异常
if info.status_code == 200:
"""表示图片上传成功"""
return ret.get("key")
else:
# 上传失败
raise Exception("图片上传七牛云失败")
- step6 回到profile中,调用封装好的七牛接口上传图片,返回文件名
try:
file_name = storage(image_data)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.THIRDERR, errmsg="上传图片失败")
- step7 将图片地址保存到数据库avatar_url字段,思考,需要将域名与文件名拼接好后保存,还是只保存文件名,为了节省空间,并且只有文件名不同,所以执行保存文件名到数据库avatar_url字段即可
try:
User.query.filter_by(id=user_id).update({"avatar_url":file_name})
db.session.commit()
except Exception as e:
db.session.rollback()
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="保存图片信息失败")
- step8 拼接图片完整链接
avatar_url = constants.QINIU_URL_DOMAIN + file_name
- step9 保存成功后,返回给前端正确响应
return jsonify(errno=RET.OK, errmsg="保存成功", data={"avatar_url": avatar_url})
四丶上传头像前端编写
1.前端个人信息HTML代码(不展示)
2.前端个人信息JS代码(不展示)
3.修改profile.html代码,将id="form-avatar"的表单中的action="/api/profile/avatar" method="post"去掉,通过导入的jquery.form.min.js插件来发送表单数据
<form id="form-avatar" enctype="multipart/form-data">
选择头像:<input type="file" accept="image/*" name="avatar">
<input type="submit" class="btn btn-success" value="上传">
</form>
4.在profile.js中进行如下编写
- step1 阻止表单默认行为
$(document).ready(function () {
$('#form-avatar').submit(function (e) {
// 阻止表单默认行为
e.preventDefault();
})
});
- step2 利用jquery.form.min.js插件通过的ajaxSubmit对表单进行异步提交
$(this).ajaxSubmit({
url:"/api/v1.0/users/avatar",
type:"post",
dataType:"json",
headers:{
"X-CSRFToken": getCookie("csrf_token")
},
success: function (resp) {
if (resp.errno == "0"){
// 上传成功
var avatarUrl = resp.data.avatar_url;
$('#user-avatar').attr("src", avatarUrl)
}else {
alert(resp.errmsg);
}
}
})
5.测试
- step1 运行项目
python manage.py runserver
- step2 输入http://127.0.0.1:5000 主页进行登录,然后进入个人信息,点击修改,选择头像点击上传后,如下图所示
- step3 查看七牛云内容管理
五丶修改用户名后端编写
1.创建视图函数以及定义路由接口
@api.route("/users/name", methods=["POST"])
@login_required
def update_name():
pass
2.逻辑编写,当用户输入昵称后,点击保存,向后端接口发送请求,携带用户填写的昵称name,以json格式发送数据,然后在后端获取name,并通过用户id,数据库操作更新name字段的值为用户输入的昵称name
- step1 获取用户id
user_id = g.user_id
- step2 获取前端发送过来的参数
req_dict = request.get_json()
name = req_dict.get("name")
- step3 判断用户是否输入用户名
# 判断用户是否输入用户名
if name is None:
return jsonify(errno=RET.NODATA, errmsg="昵称不能为空")
- step4 判断昵称是否存在
try:
user = User.query.filter_by(id=user_id).first()
# 从数据中获取用户昵称
user_name = user.name
if user_name is not None and user_name == name:
return jsonify(errno=RET.DATAEXIST, errmsg="用户名已存在")
except Exception as e:
current_app.logger.error(e)
- step5 将用户输入的name昵称保存到数据库中
try:
User.query.filter_by(id=user_id).update({"name": name})
db.session.commit()
except Exception as e:
db.session.rollback()
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="保存用户昵称失败")
- step6 最后返回正确响应
return jsonify(errno=RET.OK, errmsg="修改成功", data={"name": name})
六丶修改用户名前端编写
1.前端个人信息HTML代码(不展示)
2.前端个人信息JS代码(不展示)
3.去掉profile.html中action="/api/profile/name" method="post"
<form id="form-name">
4.在profile.js中添加脚本,当点击保存时,触发id = form-name的submit回调函数,发送users/name地址调用update_name是视图函数,将构造用户填写的name通过ajax方式传给后端,来完成后端逻辑,当后端返回响应码为0时,代表更新数据库成功,那么在前端直接跳转到登录页,进行登录,登录成功后则显示修改后的用户名了
$('#form-name').submit(function (e) {
e.preventDefault();
var name = $("#user-name").val();
var data = {
name:name
};
var jsonData = JSON.stringify(data);
$.ajax({
url:"/api/v1.0/users/name",
type:"post",
data:jsonData,
contentType:"application/json",
dataType:"json",
headers:{
"X-CSRFToken": getCookie("csrf_token")
},
success: function (resp) {
if (resp.errno == "0"){
location.href = "/login.html";
}else {
alert(resp.errmsg)
}
}
})
})
5.测试
说明:测试以18022222222账号为例
- step1 查看数据库中ih_user_profile表,获取所有用户信息
- step2 启动项目
python manage.py runserver
- step3 登录18022222222账号进入我的爱家,点击修改,进入修改页面,如下
- step4 先输入依存在的用户名,点击保存,如果打印用户名已存在,说明逻辑正确
- step5 输入不存在的昵称这里输入的为Hellotaogang,如果成功修改则,,逻辑正确
- step6 查看数据库显示为修改后的昵称,表示前后端逻辑编写正确
七丶在我的爱家上,显示头像用户名以及手机号
说明:这里可以写一个后端接口用来显示出此三项,我这里写了两个接口,第一个是显示头像的,第二个是显示用户名和手机号
1.先看看实现之前的效果
2.显示头像后端逻辑编写
- step1 定义show_avatar视图函数
@api.route("/users/show_avatar", methods=["POST"])
@login_required
def show_avatar():
pass
- step2 因为实现代码太简单,详细过程不细说
# 获取user_id
user_id = g.user_id
# 从数据库中获取avatar_url
try:
user = User.query.filter_by(id=user_id).first()
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="获取图片信息失败")
# 拼接图片完整链接
avatar_url = constants.QINIU_URL_DOMAIN + user.avatar_url
return jsonify(errno=RET.OK, errmsg="OK", data={"avatar_url": avatar_url})
3.显示用户名和手机号后端逻辑编写
- step1 定义show_name_mobile视图函数
@api.route("/users/show_name_mobile", methods=["POST"])
@login_required
def show_name_mobile():
pass
- step2 因为实现代码太简单,详细过程不细说
# 获取用户id
user_id = g.user_id
# 根据用户id 在数据库中获取对应的 用户名和手机号
try:
user = User.query.filter_by(id=user_id).first()
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="获取用户信息失败")
# 获取用户名
use_name = user.name
# 获取用户手机号
user_mobile = user.mobile
# 构造响应数据
data = {
"user_name": use_name,
"user_mobile": user_mobile
}
# 将响应数据返回给前端
return jsonify(errno=RET.OK, errmsg="OK", data=data)
4.显示头像和显示用户名和手机号前端编写(这里只演示显示头像的,后者可以自己尝试编写,基本一样,逻辑简单)
$(document).ready(function(){
$.ajax({
url:"/api/v1.0/users/show_avatar",
type:"post",
headers:{
"X-CSRFToken":getCookie("csrf_token")
},
dataType:"json",
success:function (resp) {
if (resp.errno == "0"){
var avatarUrl = resp.data.avatar_url;
$('#user-avatar').attr("src", avatarUrl)
}else {
alert(resp.errmsg);
}
}
});
5.代码实现后的效果图
八丶最终效果动图
注:这里以18111111111账号为例,进行动图演示
Flask项目之手机端租房网站的实战开发(八)的更多相关文章
- Flask项目之手机端租房网站的实战开发(三)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(一)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 一丶项目介绍 产品:关于手机移动端的租房网站 角色:在这个产品中用户包括房东与房客 功能:房东可以在这个平台发布自己的房屋,房客可 ...
- Flask项目之手机端租房网站的实战开发(二)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(十四)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(六)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(十一)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(十)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(九)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- Flask项目之手机端租房网站的实战开发(四)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
随机推荐
- Ubuntu16.04 “有线未托管”有线网络不可用问题解决
Ubuntu16.04 “有线未托管”问题解决 电脑上安装的Ubuntu16.04 是通过先安装Ubuntu Server后在通过命令 sudo tasksel 安装的Gnome桌面环境,安装完成后发 ...
- 计算机科学书籍推荐和CSS、js书籍推荐
计算机科学:<深入理解计算机系统>,这是基础知识 JavaScript:JavaScript高级程序设计:大名鼎鼎的红宝书 <精通CSS:高级Web标准解决方案>:因为我觉CS ...
- Hi3531D搭建环境时,出现的问题
1.展开SDK包得时候,运行./sdk.unpack得时候出现: 原因:ubuntu14.04中默认得是dash,要将dash改成bash. 解决方法:sudo ln -fs /bin/bash /b ...
- 学习参考《矩阵分析与应用(第二版)张贤达》PDF
要想深入理解机器学习,或者对人工智能的某个领域有所研究,都必须掌握矩阵及其应用. 学习<矩阵分析与应用第2版>时,会发现总结了大量线性代数的知识,主要是给工科生用的.归纳了不少论文中的解法 ...
- Linux 桌面玩家指南:18. 我对 Docker 的使用的学习心得
原文:Linux 桌面玩家指南:18. 我对 Docker 的使用的学习心得 特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记 ...
- 【VC++学习笔记四】MFC应用程序中框架类的获取
一.文档类中 获取视图: 先获取主窗体,在根据主窗体获取视图 pMain->GetActiveDocument();注意类型转换 由于文档中可能包含多个视图,可以按照下面函数获取: CView* ...
- ecshop微信通中微信自动登录的设置方法
ecshop微信通中微信自动登录的设置方法 来 源:共享世纪 作 者:网络 时间:2015-12-03 点击: 4017 注意:微信自动登录,必须同时满足两个条件: 第一.微信公众号必须是服务号经过认 ...
- IOS开发人员经常使用的10个Xcode插件
IOS开发人员经常使用的10个Xcode插件 申请达人,去除赞助商链接 一个合适的插件意味着它能够适应不同的开发环境,Sublime Text 和TextMate就是非常好的样例.你知道Xcode也支 ...
- CI框架源代码阅读笔记6 扩展钩子 Hook.php
CI框架同意你在不改动系统核心代码的基础上加入或者更改系统的核心功能(如重写缓存.输出等). 比如,在系统开启hook的条件下(config.php中$config['enable_hooks'] = ...
- [BZOJ4184]shallot 线段树+线性基
链接 题意:给你每个数字出现的时间和消失的时间,求每个时刻最大异或和 题解 按照时间建立线段树,线段树每个节点开个vector存一下这个时间区间有哪些数,然后递归进入的时候加入线性基,开一个栈记录一下 ...