Flask + vue 前后端分离的 二手书App

一个Flask + vue 前后端分离的 二手书App

效果展示:
https://blog.csdn.net/qq_42239520/article/details/88534955

所用技术清单
在这里插入图片描述
项目地址:项目地址
vue代码地址:vue代码地址

项目部分过程笔记:

后台:

项目结构

Secondhanbook /   项目目录apps v1__init__.py 导入 urlsurls.py  路由配置forms.pymodels.pyviewsuser_views.py  用户相关视图book_vews.py 书籍相关视图config.py  配置文件run.py  项目启动文件manage.py  数据库迁移文件Secondhanbook.py  初始化文件 utils  工具类目录............          

1. Flask_RESTful 的返回 和 缓存时候的自定义返回

flask_restful 在视图方法上加上marshal_with 装饰器,并传递你返回的模式。但当自定义时,需要返回自己的模式

return marshal(books,self.resource_fields,envelope='data')resource_fields:自定义返回模式data:  返回时,数据包装

2. 使用Flask_RESTful 下表单验证以及csrf防御

每当用户进入提交Post请求的页面,实例化一个表单form,返回csrf_token

csrf_token = form.csrf_token.current_tokenreturn restful.success(data=csrf_token)

3.路由配置

api = Api(prefix='/api')
#用户相关
api.add_resource(Login,'/login/',endpoint='login')  
......
#书籍相关
api.add_resource(BookAddView,'/bookadd/',endpoint='bookadd')
......

4.使用itsdangerous生成临时身份令牌
生成令牌

    def generate_auth_token(self,expiration=172800):#两天过期s = Serializer(config.BaseConfig.SECRET_KEY,expires_in=expiration)return s.dumps({'id':self.id})

身份检验

    def verify_auth_token(token):s = Serializer(config.BaseConfig.SECRET_KEY)try:data = s.loads(token)except Exception as e:return Noneuser = FrontUserModel.query.get(data['id'])return user

5.配置文件的书写方式,类继承的方式

class BaseConfig(object):pass
class DevelopmentConfig(BaseConfig):pass
class OnlineConfig(BaseConfig):pass    

6. celery 处理费时任务

@celery.task
def send_mail(subject,recipients,user_id):......
@celery.task
def BookCacheAdd(books):......

7.redis 存储数据bytes 问题解决

cache = redis.StrictRedis(host='127.0.0.1',port=6379,db=0,decode_responses=True)

8. 封装jsonfy的返回

class HttpCode(object):Ok = 200ParamerError = 400Unauth = 401ServerError = 500
def RestfulResult(code,message,data):return jsonify({'code':code,'message':message,'data':data})
def success(message="",data=None):return RestfulResult(HttpCode.Ok,message=message,data=data)
......

9.对axios 提交bytes类型数据进行form验证

from werkzeug.datastructures import MultiDict......myform = json.loads((request.data.decode('utf-8')))form = LoginForm(MultiDict(myform))......

10. flask 接收 接收多个文件axios 上传的多个文件


**  AddBookView  ** files = request.filesfor file in files.values():filename = upload.change_filename(secure_filename(file.filename))**upload.vue**for (var i = 0; i < this.files.length; i++) {this.formdata.append('file' + i, this.files[i])}axios.post('api/bookadd/', this.formdata, {headers: {'Content-Type': 'multipart/form-data'}}).then(this.handleAxiosDone)

11.表单对files, 输入字段验证

from werkzeug.datastructures import CombinedMultiDict
form = Yourform(CombinedMultiDict([request.form,   request.files])) //  合并 数据和文件
文件验证:
定义表单时,采用FileField这个类型
验证器导入:flask_wtf.file   
flask_wtf.file.FileRequired 验证是否为空
flask_wtf.file.FileAllowed 验证上传文件后缀名

前台部分知识点:

项目结构

......
srccommonfooter  页脚alert    提示fade        动画gallary  画廊......store... vuex相关  pageshomecomponentsheader.vue......Home.vuedetailmesign......
......

1. flask_result 返回时,提供默认值
返回数据时,当axios 未返回渲染到页面时,使用变量出错。
**** 解决方法: 定义默认值 例如有使用book.owner.username , book.owner.avatar时,否则报错无定义,并无法显示。

      book: {owner: {......Object}},

2. vuex store一个Message,供于消息提醒
项目基本上每个页面都有操作结果的提醒,封装一个消息提醒的组件 alert.vue

 <div v-show="isshow" class="alertBox" :style="{background:this.$store.state.color}">{{mymessage}}</div>
......computed: {mymessage () {return this.$store.state.message}},watch: {mymessage (e) {this.isshow = true}}
  state: {message: '默认值',color: ''},mutations: {msgchange (state, res) {state.message = res.message    // color 自定义消息state.color = res.color  // color 自定义颜色setTimeout(() => {state.message = ''state.color = ''}, 3000)}}**** 重点:必须重置,否则下一次一样的消息将不显示组件写一个发送提醒消息的方法,方便多次调用
handleemit (message, color) {this.$store.commit('msgchange', {message: message, color: color})
}

3. 登陆注册:
利用 vue mounted 生命周期函数请求后端返回的csrf_token , 以及检验本地 localStorage,token是否过期。首次登陆成功返回存储token

 localStorage.setExpire('token', res.headers.token, 1000 * 60 * 60 * 24 * 2) // 设置两天过期注册发送email 激活账号

4 . 使用better-scroll 加载更多
swiper 盒子必须小于content高度才能滚动

可以滚动后,页面将不能点击,解决:****    
this.scroll = new BScroll(this.$refs.wrapper, {click: true,......
监听下拉方法,加载更多pullUpLoad: {// 当上拉距离超过盒子高度的的时候,就派发一个上拉加载的事件(触发条件)threshold: 0}
监听事件this.scroll.on('pullingUp', () => {axios.get('/api/booklist/?start=' + this.start).then(this.handleAxiosSuccess)})*** 对于下拉加载更多,双重遍历,遍历页码对应的数据
v-for="(p,index) in page" v-for="item in booklist[index]" :key="item.id"   //  booklist[index] 为第几次下拉的返回的数据

5. vue-awesome-swiper

图片点击事件
监听事件:on: {click: function (e) {window.open(e.target.src) // 跳转到网页}}使用:<swiper :options="swiperOption">  swiperOption为参数{ loop: true,effect: 'fade'......}<!-- slides --><swiper-slide v-for ='item of swiperList' :key="item.id"><img class="swiper-img" :src="item.url" alt=""> // 传递图片url</swiper-slide></swiper>画廊 组件关键参数:// observer启动动态检查器(OB/观众/观看者),当改变swiper的样式(例如隐藏/显示)或者修改swiper的子元素时,自动初始化swiper。// 默认falseobserver: true,observeParents: true

6. 过滤器,传递data中的值,并且使用v-html 显示

v-html="$options.filters.filemotion(comment.content,emotions)"  //       emotions: [] 是data中自定义的值
本过滤器是对,表情的插入表情标签的过滤 [赞]  [哈哈]  替换成 图片
方法:
emotions格式 :  filemotion (value, emotions) {value = value.replace(/(\[.+?\])/g, (e, e1) => {for (var i in emotions) {if ((emotions[i].value.indexOf(e1)) > -1) {return '<img src="' + emotions[i].icon + '">'}}})return value}

7. axios 更改请求头:

 axios.post('/api/comment/',参数, {headers: {'Content-Type': 'application/json'......}})

8. Proxytable设置跨域,进行数据交互

    proxyTable: {'/api': {target: 'http://127.0.0.1:5000',  //目标接口域名changeOrigin: true,  //是否跨域pathRewrite: {'^/api': '/v1/api/'   //重写接口}}}

9.router 模式
路由 mode="history"模式
当前端项目结合到flask 项目中,当vue 路由为history模式时,出现“刷新页面报错404”的问题

这是因为这是单页应用…其实是因为调用了history.pushState API 所以所有的跳转之类的操作
都是通过router来实现的,解决这个问题很简单,只需要在后台配置如果URL匹配不到任何静态资源

进入新页面,不回到页面顶部解决:

  scrollBehavior (to, from, savedPosition) {return { x: 0, y: 0 }},

转载于:https://www.cnblogs.com/donghaoblogs/p/10523983.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac OS X Glut build instructions

Mac OS X Glut build instructions(在Mac上用glut库编写OpenGL程序) Wentao Sun, Autodesk, Inc. 1. Building GLUT apps under Mac OS X There are only a few modifications you need to make to the robot.c sample to get it compiled on your Mac. These instruction…

跨域方法

1.jsonp,原理利用script的src属性(像img,iframe等有src属性的都支持跨域)引入js文件&#xff0c;并在引入成功后调用回调函数&#xff0c;数据通过参数的形式传过来。 例&#xff1a; 2.window.name 3.document.domain 4.h5的方法&#xff1a;window.postMessage 5.flash 6.COR…

java多线程之wait_(三)java多线程之wait notify notifyAll

引言今天我打算讲一下Object.wait,Object.notify,Object.notifyAll这三个方法. 首先我们查看一下api看看,官方api对这几个方法的介绍.理论Object.wait(): 导致当前线程一直等待,直到另一外一个线程用同一个对象调用Object.notify或Object.notifyAll方法.换种说法,就是调用Objec…

2019 GDUT Rating Contest II : A. Taming the Herd

题面&#xff1a; A. Taming the Herd Input file: standard inputOutput file: standard outputTime limit: 1 secondMemory limit: 256 megabytesEarly in the morning, Farmer John woke up to the sound of splintering wood. It was the cows, and they were breaking out…

SQL server 系统优化--通过执行计划优化索引(1) (转)

SQL server 系统优化--通过执行计划优化索引&#xff08;1&#xff09; 前几天,远离上海&#xff0c;到了温州&#xff0c;在客户的这边处理系统慢&#xff0c;该系统每天正常down机7次左右&#xff0c;在线人员一多&#xff0c;系统运行缓慢&#xff0c;严重影响业务操作,到了…

C#中理解接口以及接口的作用

在C#的开发中&#xff0c;接口是非常重要也非常好用的。可是很多时候很多人都不是很了解接口的做用&#xff0c;以及该如何使用。下面我们就来理解接口的作用&#xff0c;并看看如何使用吧。假设我们公司有两种程序员&#xff1a;VB程序员&#xff0c;指的是用VB写程序的程序员…

c语言转化java工具_详解C语言常用的一些转换工具函数

1、字符串转十六进制代码实现&#xff1a;void StrToHex(char *pbDest, char *pbSrc, int nLen){char h1,h2;char s1,s2;int i;for (i0; i{h1 pbSrc[2*i];h2 pbSrc[2*i1];s1 toupper(h1) - 0x30; //toupper 转换为大写字母if (s1 > 9)s1 - 7;s2 toupper(h2) - 0x30;if (…

vue项目使用eslint

转载自 https://www.cnblogs.com/hahazexia/p/6393212.html eslint配置方式有两种&#xff1a; 注释配置&#xff1a;使用js注释来直接嵌入ESLint配置信息到一个文件里配置文件&#xff1a;使用一个js&#xff0c;JSON或者YAML文件来给整个目录和它的子目录指定配置信息。这些配…

mysql存储过程语法及实例

2019独角兽企业重金招聘Python工程师标准>>> 存储过程如同一门程序设计语言&#xff0c;同样包含了数据类型、流程控制、输入和输出和它自己的函数库。 --------------------基本语法-------------------- 一.创建存储过程 create procedure sp_name() begin ......…

计算机历年考研复试上机基础题(一)

abc 题目描述 设a、b、c均是0到9之间的数字&#xff0c;abc、bcc是两个三位数&#xff0c;且有&#xff1a;abcbcc532。求满足条件的所有a、b、c的值。输入描述: 题目没有任何输入。 输出描述: 请输出所有满足题目条件的a、b、c的值。 a、b、c之间用空格隔开。 每个输出占一行。…

CSS选择器的权重与优先规则

2019独角兽企业重金招聘Python工程师标准>>> 我们在使用CSS对网页元素定义样式时经常会遇到这种情况&#xff1a;要对一般元素应用一般样式&#xff0c;然后在更特殊的元素上覆盖它们。那么我们怎么样来保证我们所新定义的元素样式能覆盖目标元素上原有的样式呢&…

201671030130+词频统计软件项目报告

&#xff08;一&#xff09;需求分析 根据实验二 软件工程个人项目的要求该软件项目的基本功能要求如下&#xff1a; 1.程序可读入任意英文文本文件&#xff0c;该文件中英文词数大于等于1个。 2.程序需要很壮健&#xff0c;能读取容纳英文原版《哈利波特》10万词以上的文章。 …

php系统维护,软件系统维护主要包含什么

软件系统维护主要包含软件系统正常使用要求与定期维护、软件系统初始化安装的维护准备。软件是用户与硬件之间的接口界面&#xff0c;用户主要是通过软件与计算机进行交流。本文操作环境&#xff1a;windows系统、thinkpad t480电脑。(学习视频分享&#xff1a;编程视频)计算机…

一个C#写的调用外部进程类

2008-05-21 07:00 作者&#xff1a; 肖波 出处&#xff1a; 天极网 C# 调用外部进程的类&#xff0c;网上可以搜出很多来&#xff0c;为什么要再写一遍&#xff0c;实在是因为最近从网上拷贝了一个简单的例程用到项目中&#xff0c;运行有问题&#xff0c;后来研究了半天&#…

【编程题目】复杂链表的复制☆

76.复杂链表的复制&#xff08;链表、算法&#xff09;题目&#xff1a;有一个复杂链表&#xff0c;其结点除了有一个 m_pNext 指针指向下一个结点外&#xff0c;还有一个 m_pSibling 指向链表中的任一结点或者 NULL。其结点的 C定义如下&#xff1a;struct ComplexNode{ int m…

mssql sqlserver 不固定行转列数据(动态列)

mssql sqlserver 不固定行转列数据(动态列) 原文:mssql sqlserver 不固定行转列数据(动态列)转自:http://www.maomao365.com/?p5471摘要: 下文主要讲述动态行列转换语句&#xff0c;列名会根据行数据的不同&#xff0c; 动态的发生变化 -------------------------------------…

在php里让字体划过变色,鼠标划过字体时如何用css来实现字体变色?(代码实测)...

当我们在浏览网页时&#xff0c;鼠标划过某段文字会出现变色效果&#xff0c;这就是css字体变色&#xff0c;一方面是为了主动吸引人用户目光去点击&#xff0c;另一方面是为了防止用户点击错其他文字段落。其实这种css鼠标经过字体变色的效果是非常容易实现的。只要你略懂css知…

初识python之 APP store排行榜 蜘蛛抓取(一)

直接上干货&#xff01;&#xff01; 采用python 2.7.5-windows 打开 http://www.apple.com/cn/itunes/charts/free-apps/ 如上图可以见采用的是utf-8 编码 经过一番思想斗争 编码如下 &#xff08;拍砖别打脸&#xff09; #codingutf-8 import urllib2 import urllib …

PP团队圣经巨著《Application Architecture Guide2.0》14章-数据访问层

第十四章 数据访问层指导 概览 这一章主要描述设计数据访问层时要注意的主要原则。它们覆盖了设计数据访问层遇到的通常问题及错误。下面的图表展示了数据层怎样嵌入一个通用的应用架构。 (cnblog我的图片一直上传不了&#xff0c;报Remote server Error,只能使用网络图片了) 数…

20个Flutter实例视频教程-第03节: 不规则底部工具栏制作-1

第03节: 不规则底部工具栏制作-1 博客地址&#xff1a; https://jspang.com/post/flutterDemo.html#toc-973 视频地址&#xff1a; https://www.bilibili.com/video/av39709290?p3 视频里面的评论&#xff1a;动态组件就是可以setState的组件 flutter create demo02的项目 这里…