def del_cache_(): """ cache缓存值 :return: """ cache.set('name', 'xiaoming', timeout=30) cache.set('person', {'name': 'aaa', 'age': 20}) x = cache.get('name') print(x) cache.set_many([('name1', 'hhh'), ('name2', 'jjj')]) print(cache.get_many("name1", "name2")) print(cache.delete("name")) print(cache.delete_many("name1", "name2")) print(cache.get('person')) return 'ok'
def validate_yzm(self, data): '''对比验证码''' code = cache.get('code') input_code = data.data # 转换成小写验证 if code != input_code: raise ValidationError('验证码错误')
def send_email_code(): '''发送动态验证码''' form = SendEmailCodeForm() if request.method == 'POST' and form.validate_on_submit(): # 接收邮箱号 email = form.email.data # 判断缓存是否有值,有:表单重复提交 if cache.get(email) == 1: # 重复提交表单处理 return render_template('user/send_email_code.html', form=form, is_send_mail=1) # 生成随机动态验证码,保存到session email_code = str(random.randint(1000, 999999)) # 4~6位验证码,转为str发送邮件 # 保存到session,邮箱也要保存到session session['email_code'] = email_code session['email'] = email # 发送动态验证码 send_mail_code(email=email, email_code=email_code) is_send_mail = 1 # 标记动态验证码发送成功,用来返回给前端 # 防止重复提交:设置一唯一个标志,放入缓存 cache.set(email, 1, timeout=10) return render_template('user/send_email_code.html', form=form, is_send_mail=is_send_mail) return render_template('user/send_email_code.html', form=form)
def my_before_request(): '''用户权限验证''' # 查询网站底部信息,先从缓存中取,无则在数据库中查找,并更新缓存 g.bottom_info = cache.get('bottom_info') if not g.bottom_info: try: bottom_info = BottomInfoModel.query.filter().first() g.bottom_info = bottom_info cache.set('bottom_info', bottom_info, timeout=60 * 60 * 24) # 更新缓存,1天 except: g.bottom_info = None # 尝试获取用户id uid = session.get('uid') try: user = UserModel.query.get(uid) g.user = user # 使用g对象存储用户,这样哪个页面都能用了 except: # 查询数据库出错 g.user = user = None # 未登录,不能访问 if request.path in required_login_path and not user: return redirect(url_for('user.login')) # 已登录,不能访问 if request.path in login_not_path and user: return redirect(url_for('main.index')) # 不是管理员不能访问 if re.search(r'^/admin.*', request.path): if not user or user.is_admin != 1: # 未登录或普通用户 return abort(404) # 抛出404错误,避免被发现后台管理路径
def post(self): args = lr_parser.parse_args() mobile = args.get('mobile') code = args.get('code') cache_code = cache.get(mobile) print('code:', code) print('cache_code:', cache_code) if cache_code and code == cache_code: # 数据库中查找是否存在此mobile user = User.query.filter(User.phone == mobile).first() # 列表中是否存在用户 if not user: # 注册处理 user = User() user.phone = mobile s = '' for i in range(13): ran = random.randint(0, 9) s += str(ran) user.username = '******' + s db.session.add(user) db.session.commit() # # 登录处理,记录登录状态:session,cookie,cache(redis),token,JWT # 说明用户是登录成功的 dfjkdj-hdfjhsd34-sdjf83748-3847fnmm token = str(uuid.uuid4()).replace('-', '') + str( random.randint(100, 999)) print('token:', token) # 存储用户的登录信息 cache.set(token, mobile) return {'status': 200, 'msg': '用户登录成功', 'token': token} else: return {'errmsg': '验证码错误', 'status': 400}
def post(self): args = lr_parser.parse_args() mobile = args.get('mobile') code = args.get('code') cache_code = cache.get(mobile) print('code:', code) print('cache_code:', cache_code) if cache_code and code == cache_code: # 数据库中查找是否存在此mobile user = User.query.filter(User.phone == mobile).first() # 列表中是否存在用户 if not user: # 注册处理 user = User() user.phone = mobile s = '' for i in range(13): ran = random.randint(0, 9) s += str(ran) user.username = '******' + s db.session.add(user) db.session.commit() # # 登录处理,记录登录状态:session,cookie,cache(redis) cache.set(mobile + "_", 1) return marshal(user, user_fields) # 输出的内容 else: return {'errmsg': '验证码错误', 'status': 400}
def post(self): args = lr_parser.parse_args() mobile = args.get('mobile') code = args.get('code') cache_code = cache.get(mobile) if cache_code and code == cache_code: # if code == '1234': # 数据库中查找是否存在此mobile用户 user = User.query.filter(User.phone == mobile).first() if not user: # 无用户 # 注册处理 user = User() user.phone = mobile s = '' for i in range(10): ran = random.randint(0, 9) s += str(ran) user.username = '******' + s db.session.add(user) db.session.commit() # 登录处理 记录登录状态:session(一个用户一个session),cookie,cache(redis所有用户用一个大池子),token token = str(uuid.uuid4()).replace('-', '') + str( random.randint(100, 999)) # print('token:', token) # 存储用户的登录信息 cache.set(token, mobile) return marshal(user, user_fields) # 用装饰器则上下需返回一样格式的内容 # return {'status': 200, 'msg': '用户登录成功', 'token': token} else: return {'errmsg': '验证码错误', 'status': 400}
def post(self): args = lor_parser.parse_args() phone = args.get('phone') code = args.get('code') print(type(code), phone) cache_code = cache.get(phone) print(cache_code, type(cache_code)) if cache_code and code == str(cache_code): user = User.query.filter(User.phone == phone).first() if not user: user = User() user.phone = phone now_time = datetime.now().strftime('%Y%m%d%H%M%S') user.username = '******' + now_time db.session.add(user) db.session.commit() token = str(uuid.uuid4()) print(token, '--------') cache.set(token, phone) return jsonify(code=200, msg='登录成功', token=token) else: return jsonify(code=400, msg='验证码错误')
def check_user(): auth = request.headers.get('Authorization') if not auth: abort(401, msg='请先登录') mobile = cache.get(auth) if not mobile: abort(401, msg='无效令牌') user = User.query.filter(User.phone == mobile).first() if not user: abort(401, msg='此用户已被管理员删除') g.user = user
def check_user(): token = request.headers.get('Authorization') if not token: abort(501, msg='请先登录') phone = cache.get(token) if not phone: abort(501, msg='token失效,请重新登录') user = User.query.filter(User.phone == phone).first() if not user: abort(501, msg='用户不存在或已被删除') g.user = user
def check_user(): auth = request.headers.get('Authorization') if not auth: # 抛出异常 Raise a HTTPException for the given http_status_code. abort(401, msg='请先登录') mobile = cache.get(auth) if not mobile: abort(401, msg='无效令牌') user = User.query.filter(User.phone == mobile).first() if not user: abort(401, msg='此用户已被管理员删除') g.user = user
def message_board(): '''留言板''' form = MessageBoradForm() # get请求 try: p = int(request.args.get('page', 1)) # 页码要为整形 except: p = 1 # 查询数据,分页,按id降序 try: message_list = MessageBoardModel.query.order_by( -MessageBoardModel.id).paginate(page=p, per_page=20) except: return render_template('main/message_board.html', form=form) # post请求 # 是否登录 if request.method == 'POST' and not g.user: return render_template('main/message_board.html', form=form, message_list=message_list, msg='请先登录') # 表单验证 if request.method == 'POST' and form.validate_on_submit(): # 接收数据 content = form.content.data # 查看缓存判断是否重复提交 if cache.get(str(g.user.id) + content + request.path) == 1: return redirect(url_for('main.message_board')) # 创建对象 item = MessageBoardModel() item.content = content item.user_id = g.user.id # 提交数据库 try: db.session.add(item) db.session.commit() # 缓存,10秒内不能重复提交,唯一标识key:用户id+内容+请求路径 cache.set(str(g.user.id) + content + request.path, 1, timeout=10) return redirect(url_for('main.message_board')) except: return render_template('main/message_board.html', form=form, message_list=message_list, msg='提交失败') # get请求 return render_template('main/message_board.html', form=form, message_list=message_list)
def index(): '''首页''' # 先从缓存中获取数据,没有则到数据库查找,并更新缓存 index_brief_introduction = cache.get('index_brief_introduction') scenic_spots_list = cache.get('scenic_spots_list') image_list = cache.get('image_list') # 查询首页简介数据 if not index_brief_introduction: try: index_brief_introduction = IndexBriefIntroductionModel.query.filter( ).first() cache.set('index_brief_introduction', index_brief_introduction, timeout=60 * 60) # 1小时 except: index_brief_introduction = None # 查询景点数据 if not scenic_spots_list: try: scenic_spots_list = ScenicSpotsModel.query.order_by( -ScenicSpotsModel.num).limit(4).all() cache.set('scenic_spots_list', scenic_spots_list, timeout=60) # 60秒 except: scenic_spots_list = None # 轮播图 if not image_list: try: image_list = BannerModel.query.filter().all() cache.set('image_list', image_list, timeout=60 * 60 * 24 * 7) # 7天 except: image_list = None return render_template('main/index.html', index_brief_introduction=index_brief_introduction, scenic_spots_list=scenic_spots_list, image_list=image_list)
def email_captcha(): email = request.args.get('email') if not email: return 'empty address', 400 captcha = ''.join(map(str, np.random.randint(0, 10, 6))) if cache.get(email): return 'request too frequently' msg = Message('百团通注册验证码', recipients=[email], body='您的验证码是:%s' % captcha) try: mail.send(msg) except smtplib.SMTPException: return 'sending failed', 500 cache.set(email, captcha) return 'success', 200
def put(self): args = update_parser.parse_args() code = args.get('code') mobile = args.get('mobile') cache_code = cache.get(mobile) # 判断验证码是否输入正确 if cache_code and cache_code == code: user = User.query.filter(User.phone == mobile).first() password = args.get('password') repassword = args.get('repassword') # 判断密码是否输入一致 if password == repassword: user.password = generate_password_hash(password) db.session.commit() return {'status': 200, 'msg': '设置密码成功'} else: return {'status': 400, 'msg': '两次密码不一致'} else: return {'status': 400, 'msg': '验证码有误'}
def user_login(): if request.method == 'POST': username = request.form.get('username') pwd1 = request.form.get('password1') captcha = request.form.get('captcha') # 从session中取值 # code = session.get('pic_code') code = cache.get('code_abc') if code.lower() != captcha.lower(): flash('验证码错误') return render_template('login_captcha.html') # 查询 user = User.query.filter_by(username=username).first() if user and check_password_hash(user.password, pwd1): session['uname'] = username return redirect(url_for('blog.index')) else: print('login') return render_template('login_captcha.html')
def register(): request_form = json.loads(request.get_data(as_text=True)) username = request_form.get('username') password = request_form.get('password') email = request_form.get('email') captcha = request_form.get('captcha') if User.query.filter_by(username=username).first(): return 'username existed', 300 elif User.query.filter_by(email=email).first(): return 'email existed', 300 elif captcha != cache.get(email): return 'invalid captcha' else: user = User(username=username, password=password, email=email) db.session.add(user) db.session.commit() return 'user established'
def patch(self): args = update_parser.parse_args() phone = args.get('phone') code = args.get('code') pwd = args.get('password') reset_pwd = args.get('repassword') cache_code = str(cache.get(phone)) print(code, '----', cache_code) print(type(code), '-----', type(cache_code)) if cache_code and code == cache_code: user = User.query.filter(User.phone == phone).first() if pwd == reset_pwd: user.password = generate_password_hash(reset_pwd) db.session.commit() return jsonify(code=200, msg='密码修改成功') else: return jsonify(code=400, msg='密码不一致') else: return jsonify(code=400, msg='验证码有误')
def login(): if request.method == 'POST': f = request.args.get('f') if f == '1': # 用户名或者密码 username = request.form.get('username') password = request.form.get('password') users = User.query.filter(User.username == username).all() for user in users: # 如果flag = True表示匹配,否则密码不匹配 flag = check_password_hash(user.password, password) if flag: # # cookie实现机制 # response = redirect(url_for('user.index')) # # 最长保存多久,登录多久后失效 key,value # response.set_cookie('uid', str(user.id), max_age=1800) # return response # session机制,session当成字典使用 session['uid'] = user.id return redirect(url_for('user.index')) else: return render_template('user/login.html', msg='用户名或者密码有误') elif f == '2': # 手机号码与验证码 mobile = request.form.get('phone') code = request.form.get('code') # 先验证验证码 valid_code = cache.get(mobile) # print(valid_code) if code == valid_code: # 查询数据库 user = User.query.filter(User.phone == mobile).first() if user: # 登录成功 session['uid'] = user.id return redirect(url_for('user.index')) else: return render_template('user/login.html', msg='此号码未注册') else: return render_template('user/login.html', msg='验证码有误!') return render_template('user/login.html')
def user_login(): '''登录''' if request.method == 'POST': key = request.args.get('key') # key:1为密码登录,2为短信验证码登录,str类型 print(key, '*********************************************') if key == '1': # 密码登录 username = request.form.get('username') password = request.form.get('password') users = User.query.filter(User.username == username).all() for user in users: if check_password_hash(user.password, password): # 设置cooke,需要实例一个响应对象 # res = redirect(url_for('app.index')) # res.set_cookie('uid', str(user.id), max_age=1800) # 用户主键作为cookie # return res # 设置session, 字典形式 session['uid'] = user.id return redirect(url_for('app.index')) else: return render_template('user/login.html', msg='用户名或密码错误') elif key == '2': # 短信验证码登录 phone = request.form.get('phone') # 获取手机号 yzm = request.form.get('yzm', None) # 获取用户输入的验证码 code = cache.get(phone) # 获取真实验证码 print(code, "aaa***************************") # 判断验证码是否正确 if yzm is not None and code == yzm: user = User.query.filter(User.phone == phone).first() # 查询用户 if user: # 如果用户存在 session['uid'] = user.id return redirect(url_for('app.index')) else: return render_template('user/phone_login.html', msg='号码未注册') else: return render_template('user/phone_login.html', msg='验证码错误') return render_template('user/login.html')
def test_register2(self, client): cache.set('*****@*****.**', '123') print(cache.get('*****@*****.**')) rv = register(client, 'lzh', r'heihei', r'*****@*****.**', '123') assert rv.data == b'user established'
def get(key): return cache.get(key)
def add_scenic_spot(): '''添加景点''' cache.delete('scenic_spots_list') # 删除缓存 form = AddScenicSpotForm() is_succeed = 0 # 标志:添加成功为1,否则为0 # 有sid则为编辑景点 sid = request.args.get('sid') if sid: # 编辑景点表单验证 form = EditScenicSpotForm() # 查询id对应景点 item = ScenicSpotsModel.query.get(sid) if item and request.method == 'POST' and form.validate_on_submit(): # 接收数据 name = form.name.data content = form.content.data opening_hours = form.opening_hours.data rates = form.rates.data image = form.image.data images = request.files.getlist('images') # 图集 # 判断是否重复提交 if cache.get(name) == 1: return redirect(url_for('admin.admin_index')) # 判断是否上传有封面图 if image: # 判断上传封面图片大小,限制大小:5M size = image.read(5 * 1024 * 1024 + 1) # 限制最大读取字节大小,防止读取全部 if len(size) > 5 * 1024 * 1024: return render_template('admin/add_scenic_spot.html', form=form, image_msg='大小不能超过5M', is_succeed=is_succeed, item=item) # 将二进制图片保存到本地 image_filename = str(uuid.uuid4()) + '.jpg' # 文件名 image_path = os.path.join(settings.SCENIC_SPOT_DIR, image_filename) with open(image_path, 'wb') as f: f.write(size) item.image = '/images/scenic_spot/' + image_filename # 更新数据库 item.name = name item.content = content item.opening_hours = opening_hours if opening_hours else '24小时开放' item.rates = rates if rates else '免费' # 三元表达式 item.create_time = datetime.datetime.now().strftime( '%Y-%m-%d') # 更新时间 db.session.commit() # 判断是否上传有图集 if images[0].filename != '': # 图集处理 for img in images: # 图片后缀名验证 if '.' not in img.filename or img.filename != '' and img.filename.rsplit( '.')[1] not in ('png', 'jpg', 'gif', 'jpeg'): return render_template( 'admin/add_scenic_spot.html', form=form, images_msg='只支持png,jpg,gif,jpeg格式的图片', is_succeed=is_succeed, item=item) # 图片限制大小:15M size = img.read(15 * 1024 * 1024 + 10) # 读取15M加10字节 if len(size) > 15 * 1024 * 1024: return render_template('admin/add_scenic_spot.html', form=form, images_too_big='最大只支持15M的图片', is_succeed=is_succeed, item=item) # 创建文件名,景点id_uuid.jpg img_filename = str(item.id) + '_' + str( uuid.uuid4()) + '.jpg' # 创建文件路径 img_path = os.path.join(settings.SCENIC_SPOT_IMAGES_DIR, img_filename) # 图片保存到本地,二进制写入 with open(img_path, 'wb') as f: f.write(size) # 保存图片到数据库 try: img_item = ScenicSpotsImagesModel() img_item.image = '/images/scenic_spot_images/' + img_filename img_item.scenic_spots_id = item.id db.session.add(img_item) db.session.commit() except: return render_template('admin/add_scenic_spot.html', form=form, is_succeed=is_succeed, msg='添加失败!', item=item) # 防止重复提交,设置唯一标识,放入缓存 cache.set(name, 1, timeout=10) return render_template('admin/add_scenic_spot.html', form=form, item=item, is_succeed=1) # get请求(编辑) return render_template('admin/add_scenic_spot.html', form=form, item=item) # post请求+表单验证 if request.method == 'POST' and form.validate_on_submit(): # 接收数据 name = form.name.data content = form.content.data opening_hours = form.opening_hours.data rates = form.rates.data image = form.image.data images = request.files.getlist('images') # 图集 # 判断是否重复提交 if cache.get(name) == 1: return redirect(url_for('admin.admin_index')) # 判断上传封面图片大小,限制大小:5M size = image.read(5 * 1024 * 1024 + 1) # 限制最大读取字节大小,防止读取全部 if len(size) > 5 * 1024 * 1024: return render_template('admin/add_scenic_spot.html', form=form, image_msg='大小不能超过5M', is_succeed=is_succeed) # 将二进制图片保存到本地 image_filename = str(uuid.uuid4()) + '.jpg' # 文件名 image_path = os.path.join(settings.SCENIC_SPOT_DIR, image_filename) with open(image_path, 'wb') as f: f.write(size) # 查询数据库是否有相同的景点名称,有则更新 try: item = ScenicSpotsModel.query.filter( ScenicSpotsModel.name == name).first() if item: item.name = name item.content = content item.opening_hours = opening_hours if opening_hours else '24小时开放' item.rates = rates if rates else '免费' # 三元表达式 item.image = '/images/scenic_spot/' + image_filename item.create_time = datetime.datetime.now().strftime( '%Y-%m-%d') # 更新时间 db.session.commit() # 判断是否上传有图集 if images[0].filename != '': # 图集处理 for img in images: # 图片后缀名验证 if '.' not in img.filename or img.filename != '' and img.filename.rsplit( '.')[1] not in ('png', 'jpg', 'gif', 'jpeg'): return render_template( 'admin/add_scenic_spot.html', form=form, images_msg='只支持png,jpg,gif,jpeg格式的图片', is_succeed=is_succeed) # 图片限制大小:15M size = img.read(15 * 1024 * 1024 + 1) if len(size) > 15 * 1024 * 1024: return render_template( 'admin/add_scenic_spot.html', form=form, images_too_big='最大只支持15M的图片', is_succeed=is_succeed) # 创建文件名,景点id_uuid.jpg img_filename = str(item.id) + '_' + str( uuid.uuid4()) + '.jpg' # 创建文件路径 img_path = os.path.join( settings.SCENIC_SPOT_IMAGES_DIR, img_filename) # 图片保存到本地,二进制写入 with open(img_path, 'wb') as f: f.write(size) # 保存图片到数据库 try: img_item = ScenicSpotsImagesModel() img_item.image = '/images/scenic_spot_images/' + img_filename img_item.scenic_spots_id = item.id db.session.add(img_item) db.session.commit() except: return render_template( 'admin/add_scenic_spot.html', form=form, is_succeed=is_succeed, msg='添加失败!') # 防止重复提交,设置唯一标识,放入缓存 cache.set(name, 1, timeout=10) return render_template('admin/add_scenic_spot.html', form=form, is_succeed=1) except: return render_template('admin/add_scenic_spot.html', form=form, is_succeed=is_succeed, msg='添加失败!') # 保存到数据库 item = ScenicSpotsModel() item.name = name item.content = content item.opening_hours = opening_hours if opening_hours else '24小时开放' item.rates = rates if rates else '免费' # 三元表达式 item.image = '/images/scenic_spot/' + image_filename try: db.session.add(item) db.session.commit() # 判断是否上传有图集 if images[0].filename != '': # 图集处理 for img in images: # 图片后缀名验证 if '.' not in img.filename or img.filename != '' and img.filename.rsplit( '.')[1] not in ('png', 'jpg', 'gif', 'jpeg'): return render_template( 'admin/add_scenic_spot.html', form=form, images_msg='只支持png,jpg,gif,jpeg格式的图片', is_succeed=is_succeed) # 图片限制大小:15M size = img.read(15 * 1024 * 1024 + 1) if len(size) > 15 * 1024 * 1024: return render_template('admin/add_scenic_spot.html', form=form, images_too_big='最大只支持15M的图片', is_succeed=is_succeed) # 创建文件名,景点id_uuid.jpg img_filename = str(item.id) + '_' + str( uuid.uuid4()) + '.jpg' # 创建文件路径 img_path = os.path.join(settings.SCENIC_SPOT_IMAGES_DIR, img_filename) # 图片保存到本地,二进制写入 with open(img_path, 'wb') as f: f.write(size) # 保存图片到数据库 try: img_item = ScenicSpotsImagesModel() img_item.image = '/images/scenic_spot_images/' + img_filename img_item.scenic_spots_id = item.id db.session.add(img_item) db.session.commit() except: return render_template('admin/add_scenic_spot.html', form=form, is_succeed=is_succeed, msg='添加失败!') # 防止重复提交,设置唯一标识,放入缓存 cache.set(name, 1, timeout=10) return render_template('admin/add_scenic_spot.html', form=form, is_succeed=1) except: return render_template('admin/add_scenic_spot.html', form=form, is_succeed=is_succeed, msg='添加失败!') # get请求 return render_template('admin/add_scenic_spot.html', form=form)
def add_info(): '''发布公告''' form = AddInfoForm() is_succeed = 0 # 标志:添加成功为1,否则为0 # get请求如果带有info_id,则为编辑公告 # 编辑公告 info_id = request.args.get('info_id') if info_id: # 查询id对应公告 try: item = InfoModel.query.get(info_id) if request.method == 'POST' and form.validate_on_submit() and item: title = form.title.data # 判断是否重复提交 if cache.get(title) == 1: return redirect(url_for('admin.admin_index')) item.title = title item.content = form.content.data item.create_time = datetime.datetime.now().strftime( '%Y-%m-%d') # 更新时间 db.session.commit() # 防止重复提交,设置唯一标识,放入缓存 cache.set(title, 1, timeout=10) return render_template('admin/add_info.html', form=form, is_succeed=1) return render_template('admin/add_info.html', form=form, is_succeed=is_succeed, item=item) except: # 查询出错则转为添加公告 return render_template('admin/add_info.html', form=form, is_succeed=is_succeed) # 发布或更新公告 if request.method == 'POST' and form.validate_on_submit(): # 接收数据 title = form.title.data content = form.content.data # 判断是否重复提交 if cache.get(title) == 1: return redirect(url_for('admin.admin_index')) # 查询数据库是否有相同的公告名称,有则更新公告 try: item = InfoModel.query.filter(InfoModel.title == title).first() if item: item.title = title item.content = content item.create_time = datetime.datetime.now().strftime( '%Y-%m-%d') # 更新时间 db.session.commit() # 防止重复提交,设置唯一标识,放入缓存 cache.set(title, 1, timeout=10) return render_template('admin/add_info.html', form=form, is_succeed=1) except: return render_template('admin/add_info.html', form=form, is_succeed=is_succeed, msg='发布失败!') # 发布公告 item = InfoModel() item.title = title item.content = content try: db.session.add(item) db.session.commit() # 防止重复提交,设置唯一标识,放入缓存 cache.set(title, 1, timeout=10) return render_template('admin/add_info.html', form=form, is_succeed=1) except: return render_template('admin/add_info', form=form, is_succeed=is_succeed, msg='发布失败!') # 普通get请求(添加公告) return render_template('admin/add_info.html', form=form, is_succeed=is_succeed)
def user_dynamic(): '''用户动态''' form = UserAddDynamicForm() # 页码 try: p = int(request.args.get('page', 1)) # 页码要为整形 except: p = 1 # 查询数据,分页,按id降序 try: item = UserDynamicModel.query.order_by(-UserDynamicModel.id).paginate( page=p, per_page=15) except: return render_template('main/user_dynamic.html', form=form) # 是否登录 if request.method == 'POST' and not g.user: return render_template('main/user_dynamic.html', form=form, item=item, msg='请先登录') # 表单验证 if request.method == 'POST' and form.validate_on_submit(): # 接收数据 content = request.form.get('content') images = request.files.getlist('images') # 查看缓存,判断是否重复提交 if cache.get(str(g.user.id) + content + request.path) == 1: return redirect(url_for('main.user_dynamic')) # 文本内容保存到数据库 dynamic_item = UserDynamicModel() dynamic_item.content = content dynamic_item.user_id = g.user.id try: db.session.add(dynamic_item) db.session.commit() # 缓存,10秒内不能重复提交,唯一标识key:用户id+内容+请求路径 cache.set(str(g.user.id) + content + request.path, 1, timeout=10) except: return render_template('main/user_dynamic.html', form=form, item=item, msg='发布失败') # 没有上传图片直接重定向 if images[0].filename == '': return redirect(url_for('main.user_dynamic')) # 图片数量限制五张 if len(images) > 5: return render_template('main/user_dynamic.html', form=form, item=item, image_too_many_error='最多只能上传五张图片') # 图片处理 for image in images: # 图片后缀名验证 if '.' not in image.filename or ( image.filename != '' and image.filename.rsplit('.')[1] not in ('png', 'jpg', 'gif', 'jpeg')): return render_template('main/user_dynamic.html', form=form, item=item, image_error='只支持png,jpg,gif,jpeg格式的图片') # 图片限制大小:10M size = image.read(10 * 1024 * 1024 + 1) # 最大读取10M+1字节,防止读取全部 if len(size) > 10 * 1024 * 1024: return render_template('main/user_dynamic.html', form=form, item=item, msg='大小不能超过10M') # 创建文件名,用户id_uuid.jpg image_filename = str(g.user.id) + '_' + str(uuid.uuid4()) + '.jpg' # 创建文件路径 image_path = os.path.join(settings.UPLOAD_USER_DYNAMIC_IMAGE, image_filename) # 图片保存到本地,二进制写入 with open(image_path, 'wb') as f: f.write(size) # 保存图片到数据库 try: image_item = UserDynamicImageModel() image_item.image = '/images/upload_user_dynamic_image/' + image_filename image_item.dynamic_id = dynamic_item.id db.session.add(image_item) db.session.commit() except: return render_template('main/user_dynamic.html', form=form, item=item, msg='发布失败') return redirect(url_for('main.user_dynamic')) # get请求 return render_template('main/user_dynamic.html', form=form, item=item)
def register(): '''用户注册''' # 实例化一个表单验证对象 form = UserRegisterForm() # 1表示已发送邮件,注册成功后才返回给前端 is_send_register_mail = 1 if request.method == 'POST': # 表单验证 if form.validate_on_submit(): # 验证通过,接收数据,可使用以下两种方式 email = request.form.get('email') # POST:form,GET:args password = form.password.data code = form.code.data # 判断是否重复提交表单 if cache.get(email) == 1: return render_template('user/register.html', form=form, flag=is_send_register_mail) # 如果用户已注册,且已激活,first()得到一个对象,不加得到查询集 # 方法一,取下标 # user = UserModel.query.filter(UserModel.email == email) # user = user[0] # 方法二,first() user = UserModel.query.filter(UserModel.email == email).first() # 如果用户存在 if user: # 用户存在且已激活 if user.is_activate == 1: return render_template('user/register.html', form=form, msg='邮箱已被注册') elif user.is_delete == 1: # 恶意账户被管理员逻辑删除 return render_template('user/register.html', form=form, msg='该用户不能注册') elif user.is_delete == 0: # 用户存在但未激活,未销号,只更新用户密码,然后重新发送激活邮件 user.password = generate_password_hash( password, salt_length=9) # 密码加密 try: db.session.commit() except: # 提交数据库出错 return render_template('user/register.html', form=form, msg='注册失败') # 发邮件(异步) send_mail(email) # 防止重复提交,设置一唯一个标志,放入缓存 cache.set(email, 1, timeout=10) return render_template('user/register.html', form=form, flag=is_send_register_mail) # 用户不存在,注册新用户 user = UserModel() user.email = email user.password = generate_password_hash(password, salt_length=9) # 密码加密 try: db.session.add(user) db.session.commit() except: return render_template('user/register.html', form=form, msg='注册失败') # 发邮件(异步) send_mail(email) # 防止重复提交,设置一个唯一标志,放入缓存 cache.set(email, 1, timeout=10) return render_template('user/register.html', form=form, flag=is_send_register_mail) # 表单验证未通过 return render_template('user/register.html', form=form) # get请求 return render_template('user/register.html', form=form)