def put(self, request): # 修改个人资料 # 1、获取参数 # 用request.body获取put方式传递的参数 data = request.body # 把字节转换成字符串 data = data.decode() # 用json.loads把字符串转成字典 data = json.loads(data) location = data.get('location') min_distance = data.get('min_distance') max_distance = data.get('max_distance') min_dating_age = data.get('min_dating_age') max_dating_age = data.get('max_dating_age') dating_sex = data.get('dating_sex') # 2、判断参数 # 2.1 判断不为空 datalist = [ location, min_distance, max_distance, min_dating_age, max_dating_age, dating_sex ] intlist = [ min_distance, max_distance, min_dating_age, max_dating_age, dating_sex ] if not all(datalist): return render_json(error.PROFIEL_NOT_EMPTY, '资料不能为空') # 2.2 判断距离和年龄要是整型 # isinstance(a, int) if not all([isinstance(i, int) for i in intlist]): return render_json(1008, '年龄和距离的类型为int') # 2.3 判断最小距离不能大于最大距离 if min_distance > max_distance: return render_json(error.MIN_DIS_NOT_GT_MAX_DIS, 'min_distance > max_distance') # 2.4 判断最小年龄不能大于最大年龄 if min_dating_age > max_dating_age: return render_json(error.MIN_AGE_NOT_GT_MAX_AGE, 'min_dating_age > max_dating_age') # 3、处理逻辑 # 把数据更新到数据库 models.Profile.objects.filter(id=request.user.id).update( location=location, min_distance=min_distance, max_distance=max_distance, min_dating_age=min_dating_age, max_dating_age=max_dating_age, dating_sex=max_dating_age, ) # 4、返回响应 return render_json(data='修改个人资料成功')
def alipayback(request): query_dict = request.GET data = query_dict.dict() print(data) # 获取并从请求参数中剔除signature signature = data.pop('sign') # 创建支付宝支付对象 alipay = AliPay( appid='2016092700609211', app_notify_url=None, # 默认回调url app_private_key_path=os.path.join(settings.BASE_DIR, "alipay/app_private_key.pem"), alipay_public_key_path=os.path.join(settings.BASE_DIR, "alipay/alipay_public_key.pem"), sign_type="RSA2", debug=True) # 校验这个重定向是否是alipay重定向过来的 success = alipay.verify(data, signature) if success: # 验证成功 # 生成支付记录,改变订单状态 print('yes') return render_json('yes') else: # 验证失败 print('no') return render_json('no')
def send_sms(phone): sms_code = rand_code(4) json_data = { "sid": config.YZX_SID, "token": config.YZX_TOKEN, "appid": config.YZX_APPID, "templateid": config.YZX_TEMPLATE_ID, "param": "%s,%s" % (sms_code, 180), "mobile": phone, } res = requests.post(config.YZX_URL, json=json_data) # res.text # 返回已经编码后的数据 # res.content # 返回字节形式的数据 con = res.json() # 返回json数据 if con.get('code') == '000000': # 保存验证码到redis里面 redis_cli = get_redis_connection() redis_cli.set(f'smscode-{phone}', sms_code, 180) # return JsonResponse({'code': 0, 'data': '验证码发送成功'}) return render_json('验证码发送成功') else: # return JsonResponse({'code': error.SEND_SMS_FAIL, 'data': '验证码发送失败'}) return render_json('验证码发送失败', error.SEND_SMS_FAIL)
def rewind(request): # 连接redis,指定用rewind配置来连接 redis_cli = get_redis_connection('rewind') # 连接redis,指定用rank配置来连接 rank_cli = get_redis_connection('rank') # 用redis来保存反悔的次数,第一次默认为0 key = 'rewind-%s' % request.user.id count = redis_cli.get(key) rewind_time = int(count) if count else 0 if rewind_time < 3: now = datetime.datetime.now() # 一天的时间 - 当前时间 = 过期时间 expire_time = 24 * 3600 - now.hour * 3600 - now.minute * 60 - now.second # 设置反悔的过期时间 redis_cli.set(key, rewind_time + 1, expire_time) uid = request.user.id # 1、找出当前用户上一次划过的用户的id # latest data = Swiped.objects.filter(uid=uid).latest('time') sid = data.sid # 反悔的分数和之前喜欢和不喜欢的分数相反 # if data.mark == 'like': # rank_cli.zincrby('HOT_RANK', -5, sid) # elif data.mark == 'superlike': # rank_cli.zincrby('HOT_RANK', -7, sid) # elif data.mark == 'dislike': # rank_cli.zincrby('HOT_RANK', 5, sid) mark_dict = {'like': -5, 'dislike': 5, 'superlike': -7} rank_cli.zincrby('HOT_RANK', mark_dict[data.mark], sid) # 2、删除好友关系 uid1, uid2 = (uid, sid) if uid < sid else (sid, uid) res = Friend.objects.filter(uid1=uid1, uid2=uid2).exists() if res: Friend.objects.filter(uid1=uid1, uid2=uid2).delete() # 3、删除滑动记录 Swiped.objects.filter(uid=uid, sid=sid).delete() else: return render_json(error.REWIND_COUNT_OVER, '反悔次数到达3次,不允许反悔了') return render_json()
def sms(request): # 1, 接收参数 phone = request.POST.get('phone') # 2,判断参数 if not re.match(r'^1[3456789]\d{9}$', phone): # returnn JsonResponse({'code': error.PHONE_FORMAT_ERROR, 'data': '手机号格式错误'}) return render_json('手机号格式错误', error.PHONE_FORMAT_ERROR) # 3,处理逻辑 send_sms(phone) # 4,返回响应 # return JsonResponse({'code': 0, 'data': '响应成功'}) return render_json('响应成功')
def get_user(request): # 获取当前用户的资料 profile = request.user.profile min_dating_age = profile.min_dating_age max_dating_age = profile.max_dating_age dating_sex = profile.dating_sex # 获取当前时间的年份 current_year = datetime.date.today().year max_birth = current_year - min_dating_age min_birth = current_year - max_dating_age # 根据条件查询数据表 # 条件是用户的出生年在max_birth和min_birth之间,而且性别等于dating_sex # 条件排除掉喜欢不喜欢超级喜欢的人 # 先查出划过的用户的id swiped = Swiped.objects.filter(uid=request.user.id) sidlist = [s.sid for s in swiped] user = User.objects.filter( birth_year__gt=min_birth, birth_year__lt=max_birth, sex=dating_sex).exclude(id=request.user.id).exclude( id__in=sidlist)[:20] dicts = [] for u in user: dicts.append(model_to_dict(u)) return render_json(data=dicts)
def avater(request): # 获取上传图片信息 request.FILES.get('avater') file = request.FILES.get('avater') # 返回的是一个图片对象,对象的name属性可以返回图片的名字 filename = file.name # 自定义一个文件名称 new_file_name = 'avater_%s' % request.user.phonenum # 获取原文件类型 name, ext = os.path.splitext(filename) # 拼接成新的文件名称 new_file = new_file_name + ext # 上传的本地路径 filepath = os.path.join(settings.UPLOADS_FIEL, new_file) # 把图片上传到uploads目录 with open(filepath, 'ab') as fp: # 分段上传,chunks把上传的文件切成一小段 for chunk in file.chunks(): fp.write(chunk) # 上传到七牛 upload_qiniu(new_file, filepath) # 七牛的文件地址 url = config.QN_URL + new_file # 把七牛的文件地址保存到数据库 models.User.objects.filter(id=request.user.id).update(avatar=url) return render_json()
def send_sms(request): # 1、获取参数 phone = request.POST.get('phone') # 2、判断参数 # 2.1 不能为空 if not all([phone]): return render_json(error.PHONE_NOT_EMPTY, '手机号不能为空') # 2.2 格式是否正确 if not re.match(r'^1[3456789]\d{9}$', phone): return render_json(error.PHONE_NOT_FORMAT, '手机号格式不正确') # 3、异步执行发送短信的任务 send_sms_celery.delay(phone) return render_json()
def like_me(request): swiper = Swiped.objects.filter(sid=request.user.id, mark__in=['like', 'superlike']) # lists = [] # for s in swiper: # lists.append(model_to_dict(s)) lists = [model_to_dict(s) for s in swiper] return render_json(data=lists)
def friend(request): uid = request.user.id # 判断uid1等于当前用户或者uid2等于当前用户 friend = Friend.objects.filter(Q(uid1=uid) | Q(uid2=uid)) # 查出好友的id放入列表里面 sid = [(f.uid2 if f.uid1 == uid else f.uid1) for f in friend] user = User.objects.filter(id__in=sid) user = [model_to_dict(u) for u in user] return render_json(data=user)
def dislike(request): # 获取不喜欢的人的ID sid = request.POST.get('sid') Swiped.objects.create(uid=request.user.id, sid=sid, mark='dislike') # 不喜欢减5分 # 1、创建redis的对象 redis_cli = get_redis_connection('rank') # 2、用哪个方法来减5分 zincrby -5 redis_cli.zincrby('HOT_RANK', -5, sid) return render_json(data='成功')
def login(request): # 1、获取数据 phone = request.POST.get('phone') code = request.POST.get('code') # 2、判断数据 # 获取验证码 # redis_cli = get_redis_connection() # sms_code = redis_cli.get(f'sms_code_{phone}').decode() # print(sms_code) # TODO 放了测试方便,先注释掉这段代码,上线时一定要打开 ''' # 2.0判断验证码是否过期 if not sms_code: return render_json(error.CODE_EXPIRE, '验证码过期') # 2.1 判断验证码是否正确 if sms_code != code: return render_json(error.CODE_ERROE, '验证码不正确') # 2.2 判断手机号和验证码不能为空 if not all([phone, code]): return render_json(error.PHONE_SMS_NOT_EMPTY, '手机号和验证码不能为空') # 2.3 判断手机号的格式 if not re.match(r'^1[3456789]\d{9}$', phone): return render_json(error.PHONE_NOT_FORMAT, '手机号格式不正确') ''' # 3、处理逻辑 # 逻辑:如果表里面有这个用户,旧直接取出数据,如果没有,直接新增用户数据 # user = models.User.objects.filter(phonenum=phone).exists() # if not user: # models.User.objects.create(phonenum=phone, nickname=phone) # 如果有数据那么user就是查出来的对象,created是0 # 如果没有数据,那么会新增数据,user就是新增数据的对象,created就是1 user, created = models.User.objects.get_or_create( phonenum=phone, defaults={"nickname": phone}) # 用session保存用户的数据 request.session['id'] = user.id # 4、返回响应 return render_json()
def get(self, request): # 获取个人资料 # id = request.session.get('id') # user = models.User.objects.get(id=id) # profile = user.profile # 查处用户资料 profile = request.user.profile # data = {} # data['id'] = profile.id # data['min_dating_age'] = profile.min_dating_age # data['max_dating_age'] = profile.max_dating_age # model_to_dict作用是把模型对象转换成字典形式 return render_json(data=model_to_dict(profile))
def process_request(self, request): # 指定白名单 white_name = ['/user/login/', '/user/sms/', '/orders/pay/', '/orders/alipayback/'] url = request.path # 如果在白名单,直接return,返回None,就会执行view视图 if url in white_name: return id = request.session.get('id') if not id: return render_json(error.USER_NOT_LOGIN, '用户未登陆') # 如果用户登录,就把用户的信息绑定到request.user属性中 request.user = User.objects.get(id=id)
def superlike(request): uid = request.user.id # 获取超级喜欢的人的ID sid = int(request.POST.get('sid')) Swiped.objects.create(uid=uid, sid=sid, mark='superlike') # 超级喜欢加7分 # 1、创建redis的对象 redis_cli = get_redis_connection('rank') # 2、用哪个方法来减5分 zincrby -5 redis_cli.zincrby('HOT_RANK', 7, sid) # 判断当前用户喜欢的用户有没有喜欢过我 res = Swiped.objects.filter(uid=sid, sid=uid, mark__in=['like', 'superlike']).exists() if res: # 比较两个id的大小,小的赋值给uid1,大的赋值给uid2 uid1, uid2 = (uid, sid) if uid < sid else (sid, uid) Friend.objects.create(uid1=uid1, uid2=uid2) return render_json(data='成功')
def commits(request): # 1、获取数据 info = request.POST.get('info') # 2、转成字典 info = json.loads(info) info = {int(gid): int(gcount) for gid, gcount in info.items()} # 后端处理需求 # 获取商品id,查询库存是否满足 # 取出金额,生成订单 # 减库存、加销量 uid = request.user.id # 订单编号按照年月日时分秒来生成,后面加上9位的用户id order_code = datetime.datetime.now().strftime( "%Y%m%d%H%M%S") + "%09d" % uid # 开启事务 with transaction.atomic(): # 创建事务的保存点 save_id = transaction.savepoint() # 先生成总订单 orderinfo = OrderInfo.objects.create(uid=uid, order_code=order_code, total_count=sum(info.values()), total_amount=0) total_price = 0 # 循环info字典中商品,判断库存,获取金额 for good_id, good_count in info.items(): while True: # 先获取商品id对应的商品数据 good = Goods.objects.get(id=good_id) # 使用悲观锁 # good = Goods.objects.select_for_update().get(id=good_id) # 判断库存不够 if good.stock < good_count: # 回滚事务 transaction.savepoint_rollback(save_id) return render_json(error.STOCK_NOT_FILLED, '商品库存不足') # 模拟并发操作 import time time.sleep(5) # 减库存加销量 # good.stock = good.stock - good_count # good.sales = good.sales + good_count # good.save() # 使用乐观锁操作 stock_new = good.stock - good_count sales_new = good.sales + good_count print(uid, '----', good.id, '-----', good.stock) res = Goods.objects.filter(id=good.id, stock=good.stock).update( stock=stock_new, sales=sales_new, ) if res == 0: continue # # 回滚事务 # transaction.savepoint_rollback(save_id) # return render_json(data='服务器忙,请稍后操作') # 取出商品总金额 total_price += good.price * good_count # 生成子订单 OrderDetail.objects.create(uid=uid, order_code=order_code, goods_id=good.id, counts=good_count, price=good.price) break # 保存总订单的总金额 orderinfo.total_amount = total_price orderinfo.save() # 提交事务 transaction.savepoint_commit(save_id) return render_json(data='订单生成成功')