def put(self, request): '''实现邮箱添加逻辑''' # 接收参数 json_str = request.body.decode() json_dict = json.loads(json_str) email = json_dict['email'] print("邮箱是:", email) # 校验参数 if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email): return http.HttpResponseForbidden('参数email有误') # 赋值email字段 try: request.user.email = email request.user.save() except Exception as e: logger.error(e) return http.JsonResponse({ 'code': RETCODE.DBERR, 'errmsg': '添加邮箱失败' }) # 4.异步发送邮件 from apps.users.utils import generate_verify_email_url verify_url = generate_verify_email_url(request.user) from celery_tasks.email.tasks import send_verify_email send_verify_email.delay(email, verify_url) # 响应添加邮箱结果 return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加邮箱成功'})
def delete(self, request, address_id): address = Address.objects.get(id=address_id) try: address.is_deleted = True address.save() except Exception as e: logger.error(e) return http.JsonResponse({ 'code': RETCODE.DBERR, 'errmsg': '删除地址失败' }) # 响应删除结果给前端 return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '删除地址成功'})
def get(self,request): '''Oauth2.0认证''' # 接收code code = request.GET.get('code') if not code: return http.HttpResponseForbidden('缺少code') # 创建工具对象 oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI) try: # 使用code向QQ服务器请求access_token access_token = oauth.get_access_token(code) # 使用access_token向QQ服务器请求openid openid = oauth.get_open_id(access_token) except Exception as e: logger.error(e) return http.HttpResponseServerError('OAuth2.0认证失败') # 使用openid判断该QQ用户是否绑定过商城 try: oauth_user = OAuthQQUser.objects.get(openid=openid) except OAuthQQUser.DoesNotExist: # 如果openid没绑定美多商城用户 # 加密opendid 使用isdangerous secret_openid = SecretOauth().dumps({'openid':openid}) context = {'openid':secret_openid} return render(request,'oauth_callback.html',context) else: # 如果openid已绑定美多商城用户 qq_user = oauth_user.user login(request,qq_user) # 响应结果 next = request.GET.get('state') response = redirect(next) # 登录时候将用户名写入cookie response.set_cookie('username',qq_user.username,max_age=3600*24*14) return response
def send_verify_email(self, to_email, verify_url): """ 发送验证邮箱邮件 :param to_email: 收件人邮箱 :param verify_url: 验证链接 :return: None """ subject = "美多商城邮箱验证" html_message = '<p>尊敬的用户您好!</p>' \ '<p>感谢您使用美多商城。</p>' \ '<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>' \ '<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url) try: send_mail(subject, "", settings.EMAIL_FROM, [to_email], html_message=html_message) except Exception as e: logger.error(e) # 有异常自动重试三次 raise self.retry(exc=e, max_retries=3)
def put(self, request, address_id): # 根据参数获取对象 address = Address.objects.get(id=address_id) try: # 设置为默认地址 request.user.default_address = address request.user.save() except Exception as e: logger.error(e) return http.JsonResponse({ 'code': RETCODE.DBERR, 'errmsg': '设置默认地址失败' }) # 响应设置默认地址结果 return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '设置默认地址成功'})
def check_verify_email_token(token): """ 验证token并提取user :param token: 用户信息签名后的结果 :return: user, None """ from utils.secret import SecretOauth try: token_dict = SecretOauth().loads(token) except BadData: return None try: user = User.objects.get(id=token_dict['user_id'], email=token_dict['email']) except Exception as e: logger.error(e) return None else: return user
def post(self, request): # 接收参数 old_pwd = request.POST.get('old_pwd') new_pwd = request.POST.get('new_pwd') new_cpwd = request.POST.get('new_cpwd') # 校验参数 if not all([old_pwd, new_pwd, new_cpwd]): return http.HttpResponseForbidden('缺少必传参数') # 校验密码是否正确 result = request.user.check_password(old_pwd) if not result: return render(request, 'user_center_pass.html', {'origin_pwd_errmsg': '原始密码错误'}) if not re.match(r'^[0-9A-Za-z]{8,20}$', new_pwd): return http.HttpResponseForbidden('密码最少8位,最长20位') if new_pwd != new_cpwd: return http.HttpResponseForbidden('两次输入的密码不一致') # 修改密码 try: request.user.set_password(new_pwd) request.user.save() except Exception as e: logger.error(e) return render(request, 'user_center_pass.html', {'change_pwd_errmsg': '修改密码失败'}) # 清除状态保持的信息 logout(request) response = redirect(reverse('users:login')) response.delete_cookie('username') # 响应修改密码的结果,重定向到了登录页面 return response
def put(self, request, address_id): # 接收参数 json_dict = json.loads(request.body.decode()) title = json_dict.get('title') try: # 查询地址 address = Address.objects.get(id=address_id) # 设置默认标题 address.title = title address.save() except Exception as e: logger.error(e) return http.JsonResponse({ 'code': RETCODE.DBERR, 'errmsg': '设置地址标题失败' }) # 4.响应删除地址结果 return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '设置地址标题成功'})
def get(self, request): """实现邮箱验证逻辑""" # 接收参数 token = request.GET.get('token') # 校验参数:判断token是否为空和过期,提取user if not token: return http.HttpResponseBadRequest('缺少token') user = check_verify_email_token(token) if not user: return http.HttpResponseForbidden('无效的token') # 修改email_active的值为True try: request.user.email_active = True request.user.save() except Exception as e: logger.error(e) return http.HttpResponseServerError('激活邮件失败') # 返回邮箱验证结果 return redirect(reverse('users:info'))
def get(self, request): # 接收参数 area_id = request.GET.get('area_id') # 如果没有area_id ,说明没有省份数据 if not area_id: # 读取省份缓存数据 province_list = cache.get('province_list') # 判断是否有省数据的缓存 if not province_list: # 提供省份数据 try: province_model_list = Area.objects.filter( parent__isnull=True) # 遍历省份数据 province_list = [] for province_model in province_model_list: province_list.append({ 'id': province_model.id, 'name': province_model.name, }) except Exception as e: logger.error(e) return http.JsonResponse({ 'code': RETCODE.DBERR, 'errmsg': '省份数据错误' }) # 写入省份缓存数据 cache.set('province_list', province_list, 3600) # 响应省份数据 return http.JsonResponse({ 'code': RETCODE.OK, 'errmsg': 'OK', 'province_list': province_list }) else: # 读取市区缓存数据 sub_data = cache.get('sub_area_' + area_id) # 判断是否有市区缓存的数据 if not sub_data: # 提供市区数据 try: parent_model = Area.objects.get(id=area_id) sub_model_list = parent_model.subs.all() # 序列化市区数据 sub_list = [] for sub_model in sub_model_list: sub_list.append({ 'id': sub_model.id, 'name': sub_model.name, }) sub_data = { 'id': parent_model.id, 'name': parent_model.name, 'subs': sub_list, } except Exception as e: logger.error(e) return http.JsonResponse({ 'code': RETCODE.DBERR, 'errmsg': '城市或区数据错误' }) # 存储市区缓存数据 cache.get('sub_area_' + area_id, sub_data, 3600) # 响应市区数据 return http.JsonResponse({ 'code': RETCODE.OK, 'errmsg': 'OK', 'sub_data': sub_data })
def post(self, request): # 判断地址是否大于20 count = Address.objects.filter(user=request.user).count() if count > 20: return http.JsonResponse({ 'code': RETCODE.THROTTLINGERR, 'errmsg': '超过地址数量上限' }) # 接收参数 json_str = request.body.decode() json_dict = json.loads(json_str) receiver = json_dict.get('receiver') province_id = json_dict.get('province_id') city_id = json_dict.get('city_id') district_id = json_dict.get('district_id') place = json_dict.get('place') mobile = json_dict.get('mobile') tel = json_dict.get('tel') email = json_dict.get('email') # 校验参数 if not all( [receiver, province_id, city_id, district_id, place, mobile]): return http.HttpResponseForbidden('缺少必传参数') if not re.match(r'^1[3-9]\d{9}$', mobile): return http.HttpResponseForbidden('参数mobile有误') if tel: if not re.match( r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel): return http.HttpResponseForbidden('参数tel有误') if email: if not re.match( r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email): return http.HttpResponseForbidden('参数email有误') # 写入参数 try: address = Address.objects.create(user=request.user, title=receiver, receiver=receiver, province_id=province_id, city_id=city_id, district_id=district_id, place=place, mobile=mobile, tel=tel, email=email) # 设置默认地址 if not request.user.default_address: request.user.default_address = address request.user.save() except Exception as e: logger.error(e) return http.JsonResponse({ 'code': RETCODE.DBERR, 'errmsg': '新增地址失败' }) # 构造响应数据 address_dict = { "id": address.id, "title": address.title, "receiver": address.receiver, "province": address.province.name, "city": address.city.name, "district": address.district.name, "place": address.place, "mobile": address.mobile, "tel": address.tel, "email": address.email, } # 响应保存结果 return http.JsonResponse({ 'code': RETCODE.OK, 'errmsg': '新增地址成功', 'address': address_dict })
def put(self, request, address_id): # 接收参数 json_dict = json.loads(request.body.decode()) receiver = json_dict.get('receiver') province_id = json_dict.get('province_id') city_id = json_dict.get('city_id') district_id = json_dict.get('district_id') place = json_dict.get('place') mobile = json_dict.get('mobile') tel = json_dict.get('tel') email = json_dict.get('email') # 校验参数 if not all( [receiver, province_id, city_id, district_id, place, mobile]): return http.HttpResponseForbidden('缺少必传参数') if not re.match(r'^1[3-9]\d{9}$', mobile): return http.HttpResponseForbidden('参数mobile有误') if tel: if not re.match( r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel): return http.HttpResponseForbidden('参数tel有误') if email: if not re.match( r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email): return http.HttpResponseForbidden('参数email有误') # 修改地址 try: Address.objects.filter(id=address_id).update( user=request.user, title=receiver, receiver=receiver, province_id=province_id, city_id=city_id, district_id=district_id, place=place, mobile=mobile, tel=tel, email=email) except Exception as e: logger.error(e) return http.JsonResponse({ 'code': RETCODE.DBERR, 'errmsg': '更新地址失败' }) # 构造响应数据 address = Address.objects.get(id=address_id) address_dict = { "id": address.id, "title": address.title, "receiver": address.receiver, "province": address.province.name, "city": address.city.name, "district": address.district.name, "place": address.place, "mobile": address.mobile, "tel": address.tel, "email": address.email } # 返回给前端 return http.JsonResponse({ 'code': RETCODE.OK, 'errmsg': '更新地址成功', 'address': address_dict })
def get(self, request, mobile): # 接收参数 uuid = request.GET.get('image_code_id') image_code = request.GET.get('image_code') print("---------------") print("图片 uuid", uuid) print("---------------") print("用户输入验证码内容", image_code) print("---------------") # 和图片验证码redis连接取uuid from django_redis import get_redis_connection image_redis_client = get_redis_connection('verify_image_code') redis_img_code = image_redis_client.get(uuid) # 校验 if redis_img_code is None: return JsonResponse({'code': "4001", 'errmsg': "图形验证码失效了"}) # 删除 try: image_redis_client.delete(uuid) except Exception as e: logger.error(e) # 将用户输入图片验证码和Redis中的验证码进行对比 if image_code.lower() != redis_img_code.decode().lower(): return JsonResponse({'code': '4001', 'errmsg': '输入图形验证码有误'}) # 生成短信验证码,在redis中存储 from random import randint sms_code = "%06d" % randint(0, 999999) sms_code_redis = get_redis_connection('sms_code') # 判断发送短信是否频繁 send_flag = sms_code_redis.get('send_flag_%s' % mobile) if send_flag: return http.JsonResponse({ 'code': RETCODE.THROTTLINGERR, 'errmsg': '发送短信过于频繁' }) # 创建redis管道 p1 = sms_code_redis.pipeline() # 保存短信验证码 p1.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code) # 重新写入send_flag p1.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1) # 执行管道请求 p1.execute() # 让第三方 容联云 发送短信 # from libs.yuntongxun.sms import CCP # CCP().send_template_sms(mobile,[sms_code,5],1) # 实现异步发送短信 from celery_tasks.sms.tasks import ccp_send_sms_code ccp_send_sms_code.delay(mobile, sms_code) print("当前手机验证码是:", sms_code) # 响应前端结果 return http.JsonResponse({'code': '0', 'errmsg': '发送短信成功'})