1.异步用户登录\登出接口开发
1.设计公共响应数据类型
文件地址:utils/response404.py
from django.http import JsonResponseclass BadRequestJsonResponse(JsonResponse):status_code = 400def __init__(self, err_list, *args, **kwargs):data = {"error_code":"400000","error_msg":"参数格式不正确","error_list":err_list}super().__init__(data,*args, **kwargs)class MethodNotAllJsonResponse(JsonResponse):status_code = 405def __init__(self, err_list, *args, **kwargs):data = {"error_code":"405000","error_msg":"请求方式不被允许","error_list":err_list}super().__init__(data,*args, **kwargs)
2.设计accounts响应数据结构
新建文件:system/serializers.py
from utils.serializers import BaseSerializer
#返回用户基本信息
class UserSerializers(BaseSerializer):#重写父类to_dict函数def to_dict(self):user = self.objreturn {'nickname': user.nickname,'avatar': user.avatar.url}
#返回用户详细信息
class UserProfileSerializers(BaseSerializer):#重写父类to_dict函数def to_dict(self):profile = self.objreturn {'real_name': profile.real_name,'sex':profile.sex,'sex_display':profile.get_sex_display()}
3.视图函数-服务端的处理过程
文件地址:accounts/views.py
def user_api_login(request):#确定请求方式if request.method == 'POST':#表单验证form = LoginForm(request.POST)#通过验证,则执行登录if form.is_valid():# 返回内容是登录用户的信息user = form.do_login(request)#获得用户详细信息profile = user.profile#合成返回数据data = {'user':serializers.UserSerializers(user).to_dict(),'profile':serializers.UserProfileSerializers(profile).to_dict()}return http.JsonResponse(data)else:#没有通过表单验证,返回错误信息err = json.load(form.errors.as_json())return BadRequestJsonResponse(err)else:#没有请求方式return MethodNotAllJsonResponse([{"detail": "Method not allowed. Only POST is allowed."}])def user_api_logout(request):logout(request)return http.HttpResponse(status=201)
4.配置路由地址
文件地址:accounts/urls.py
from django.urls import path
from accounts import views
urlpatterns = [#用户登录(异步提交)path('user/api/login/',views.user_api_login,name='user_api_login'),#用户登出(异步提交)path('user/api/logout/',views.user_api_logout,name='user_api_logout')
]
2.用户详情接口开发
1.设计公共响应数据类型
文件地址:utils/response404.py
class UnauthorizedJsonResponse(JsonResponse):status_code = 401def __init__(self, *args, **kwargs):data = {"error_code":"401000","error_msg":"请登录",}super().__init__(data,*args, **kwargs)
2.视图函数-服务端的处理过程
文件地址:accounts/views.py
class UserDetailView(View):#用户详情接口def get(self, request):#获取用户信息user = request.user#判断用户状态是登录还是未登录if not user.is_authenticated:#未登录状态返回‘401’状态码return UnauthorizedJsonResponse()else:#返回详细信息profile = user.profiledata = {'user':serializers.UserSerializers(user).to_dict(),'profile':serializers.UserProfileSerializers(profile).to_dict()}return http.JsonResponse(data)#向客户端浏览器中响应数据
3.配置路由地址
文件地址:accounts/urls.py
from django.urls import path
from accounts import views
urlpatterns = [path('user/api/info/',views.UserDetailView.as_view(),name='user_api_info')
]
3.短信验证接口开发
1.设计公共响应数据类型
文件地址:utils/response404.py
class ServerErrorJsonResponse(JsonResponse):status_code = 500def __init__(self, *args, **kwargs):data = {"error_code":"500000","error_msg":"服务端正忙,请稍后再试",}super().__init__(data,*args, **kwargs)
2.验证码表单发送
新建文件:system/forms.py
import random
import re
from django import forms
from django.core.cache import cache
from pymongo import timeoutclass SendSmsCodeForm(forms.Form):#发送验证码phone_num = forms.CharField(label='手机号码',required=True,error_messages={'required':'请输入手机号码'})def clean_phone_num(self):#验证是否为手机号码phone_num = self.cleaned_data['phone_num']pattern = r'^1[0-9]{10}$'if not re.search(pattern, phone_num):raise forms.ValidationError('手机号码%s输入不正确',code='invalid_phone',params=(phone_num,))return phone_numdef send_sms_code(self):#生成验证码并发送sms_code = random.randint(100000,999999)phone_num = self.cleaned_data.get('phone_num',None)try:#将验证码存在radis中# key = 'sms_code_{}'.format(phone_num)time_out = 5*60# cache.set(key,sms_code,time_out)return {'phone_num': phone_num,'sms_code': sms_code,'time_out': time_out}except Exception as e:print(e)return None
3.系统视图函数
文件地址:system/views.py
class SmsCodeView(FormView):form_class = SendSmsCodeFormdef form_valid(self, form):#表单通过验证,生成并获得验证码data = form.send_sms_code()if data is not None:return http.JsonResponse(data,status=201)return ServerErrorJsonResponse()def form_invalid(self, form):#表单未通过验证err_list = json.loads(form.errors.as_json())return BadRequestJsonResponse(err_list)
4.配置路由
文件地址:system/urls.py
from django.urls import path
from system import views
urlpatterns= [path('send/sms/',views.SmsCodeView.as_view(),name='send_sms')
]
5.效果图示
向指定的手机号发送随机验证码
4.注册用户
1.登录日志&装饰器
文件地址:accounts/models.py
class User(AbstractUser):avatar = models.ImageField("头像", null=True, upload_to="avatar/%Y%m")nickname = models.CharField("昵称", max_length=32, unique=True)class Meta:db_table = "account_user"👇def add_login_record(self, **kwargs):#写入日志,保存登入历史【把传入的参数kwargs,创建在日志中】。self.login_records.create(**kwargs)@propertydef avatar_url(self):return self.avatar.url if self.avatar else ''👆
文件地址:accounts/serializers.py
2.注册表单
文件地址:accounts/forms.py
这段代码定义了一个 Django 注册表单类:
用于验证用户输入的手机号码、密码、昵称和验证码,
并在验证通过后执行用户注册流程,包括创建用户、登录和记录登录信息。
class RegisterForm(forms.Form):#用户名username = forms.CharField(label='手机号码',max_length=16,required=True,error_messages={'required':'请输入手机号码'})# 密码password = forms.CharField(label='密码',max_length=128,required=True,error_messages={'required':'请输入密码'})# 昵称nickname = forms.CharField(label='昵称',max_length=16,required=True,error_messages={'required':'请输入昵称'})# 验证码sms_code = forms.CharField(label='验证码',max_length=6,required=True,error_messages={'required':'请输入验证码'})def clean_username(self):#验证用户名username = self.cleaned_data['username']pattern = r'^1[0-9]{10}$'if not re.search(pattern,username):raise forms.ValidationError('手机号码%s输入不正确',code='invalid_phone',params=(username,))#利用数据模型对用户内容进行验证if User.objects.filter(username=username).exists():raise forms.ValidationError('手机号码已被使用')return usernamedef clean_nickname(self):#验证昵称nickname = self.cleaned_data['nickname']if User.objects.filter(nickname=nickname).exists():raise forms.ValidationError('昵称已被使用')return nickname#【数据获取】def clean(self):data = super().clean()if self.errors:returnphone_num = self.cleaned_data.get('username',None)sms_code = self.cleaned_data.get('sms_code', None)#注册验证码存入redis中return datadef do_register(self,request):#执行注册data = self.cleaned_dataversion = request.headers.get('version','')source = request.headers.get('source','')try:#1.写入基础信息user = User.objects.create_user(username=data.get('username', None),password=data.get('password', None),nickname=data.get('nickname', None))#2.写入详细信息profile = Profile.objects.create(user = user,username = user.username,version = version,source = source,)#3.登录login(request, user)#4.获取最后登录时间user.last_login = now()# 保存数据user.save()#获得IP地址ip = request.META.get('REMOTE_ADDR', '')# 4.写入日志user.add_login_record(username=user.username,ip=ip,source=source,version=version)return user,profileexcept Exception as e:print(e)return None
3.视图函数
文件地址:accounts/views.py
class UserRegisterView(FormView):#用户注册接口form_class = RegisterForm #表单验证类http_method_names = ['post'] #请求方式def form_valid(self, form):#验证通过result = form.do_register(request=self.request)#调用注册函数,完成注册步骤if result is not None:#合成响应数据user,profile = resultdata = {'user':serializers.UserSerializers(user).to_dict(),'profile':serializers.UserProfileSerializers(profile).to_dict()}#响应数据数据return http.JsonResponse(data, status=201)return ServerErrorJsonResponse()def form_invalid(self, form):#验证失败err_list = json.loads(form.errors.as_json())return BadRequestJsonResponse(err_list)
4.配置路由
文件地址:accounts/urls.py
from django.urls import path
from system import views
urlpatterns= [path('user/api/register/',views.UserRegisterView.as_view(),name='user_api_register')
]