目录
今天来谈谈基于DRF写接口时可能会遇到的几个问题吧
1. 用户修改个人信息(用户名, 邮箱, 密码等等)
其实类似于修改用户名, 邮箱,头像等信息逻辑都如出一辙,但是修改密码时时有些许不同的,相信很多朋友在写代码的时候都遇到过这样的问题。
在这里我们来举一个例子,对于修改信息的一系列操作我们可以封装一个用户相关操作的视图集(切记此类操作要设置权限校验),之后我们就可以定义相关的函数来对用户信息进行修改,这里我们假设修改用户的昵称。直接看代码。
def update_name(self, request, *args, **kwargs):
"""
修改用户昵称
:param request:
:param args:
:param kwargs:
:return:
"""
# 获取参数
last_name = request.data.get('last_name')
# 校验参数
if not last_name:
return Response({'message': "last_name不能为空"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
# 修改用户名
user = request.user
user.last_name = last_name
# 保存
user.save()
return Response({'message': "用户名修改成功"}, status=status.HTTP_200_OK)
相信大家都能看的懂,其他的也都是照葫芦画瓢,这里就体现出了修改密码的特殊之处。
众所周知,密码在数据库中是加密保存的,如果我们像修改昵称一样直接赋值给通过request对象获取到的密码,那么将会出现在数据库中"加密后"的密码和你想要修改的密码为同一个的情况,这样我们当然无法使用这个密码登录啦。
为了解决这个问题,django特地提供了一个set_password方法(接下来是完整的修改密码逻辑,为了严谨,添加了获取验证码的功能,相信大家也都能看懂,如果你没有写过发送验证码这个接口,建议先去写一下,阿里云有自动生成的SDK,很方便(可能他生成的SDK有点繁琐,如果想要简单一点的请直接联系博主)
def update_password(self, request, *args, **kwargs):
"""
修改密码
:param request:
:param args:
:param kwargs:
:return:
"""
# 获取参数
password = request.data.get('password')
password_confirmation = request.data.get('password_confirmation')
mobile = request.data.get('mobile')
codeID = request.data.get('codeID')
code = request.data.get('code')
user = request.user
# 如果手机号正确 发送验证那
res = re.match(r'^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$', mobile)
if not res:
return Response({'error': "无效的手机号"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
if not mobile:
return Response({"message": "手机号不能为空"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
if mobile == user.mobile:
result = self.verif_code(code, codeID, mobile)
if result:
return Response(result, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
else:
return Response({"message": "该手机号不是您绑定的手机号"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
# 参数校验
if not password:
return Response({"message": "密码不能为空"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
# 校验密码是否输入一致
if password != password_confirmation:
return Response({'error': "两次密码输入不一致"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
# 校验密码长度
if not (6 <= len(password) <= 18):
return Response({'error': "密码长度需在6-18位之间"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
# 修改密码
user = request.user
user.set_password(password)
user.save()
return Response({'message': "密码修改成功 请重新登录"}, status=status.HTTP_200_OK)
2. DRF提供的过滤和排序功能
因为可能涉及到开发购物平台,所以可能有按需查找排序等要求。
-
在终端下载django-filter
pip install django-filter
2.在settings文件中配置
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend',
'rest_framework.filters.OrderingFilter'],
}
-
最后在有需要排序的视图中添加即可
# 在括号中添加需要过滤的字段
filterset_fields = ('group', 'recommend')
# 在括号中添加需要排序的字段
ordering_fields = ('sales', 'price', 'id')
3.权限校验所需的simplejwt
-
安装djangorestframework-simplejwt
pip install djangorestframework-simplejwt
-
在settings文件中配置
REST_FRAMEWORK = { SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5), # 访问令牌的有效时间 "REFRESH_TOKEN_LIFETIME": timedelta(days=7), # 刷新令牌的有效时间 "ROTATE_REFRESH_TOKENS": False, # 若为True,则刷新后新的refresh_token有更新的有效时间 "BLACKLIST_AFTER_ROTATION": True, # 若为True,刷新后的token将添加到黑名单中, "UPDATE_LAST_LOGIN": False, "ALGORITHM": "HS256", # 对称算法:HS256 HS384 HS512 非对称算法:RSA "SIGNING_KEY": SECRET_KEY, "VERIFYING_KEY": None, # if signing_key, verifying_key will be ignore. "AUDIENCE": None, "ISSUER": None, 'JWT_URL': None, 'LEEWAY': 0, 'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule', "AUTH_HEADER_TYPES": ("Bearer",), # Authorization: Bearer <token> "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION", # if HTTP_X_ACCESS_TOKEN,X_ACCESS_TOKEN: Bearer <token> "USER_ID_FIELD": "id", # 使用唯一不变的数据库字段,将包含在生成的令牌中以标识用户 "USER_ID_CLAIM": "user_id", "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), "TOKEN_TYPE_CLAIM": "token_type", "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser", "JTI_CLAIM": "jti", "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp", "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5), "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1), } }
-
在app中注册rest_framework_simplejwt