Vue全栈开发旅游网项目(10)-用户管理后端接口开发

1.异步用户登录\登出接口开发

1.设计公共响应数据类型

文件地址:utils/response404.py

from django.http import JsonResponse

class BadRequestJsonResponse(JsonResponse):
    status_code = 400

    def __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 = 405

    def __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.obj
        return {
            'nickname': user.nickname,
            'avatar': user.avatar.url
        }
#返回用户详细信息
class UserProfileSerializers(BaseSerializer):
    #重写父类to_dict函数
    def to_dict(self):
        profile = self.obj
        return {
            '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 = 401
    def __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.profile
            data = {
                '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 = 500
    def __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 timeout

class 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_num

    def 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 = SendSmsCodeForm

    def 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)
    @property
    def 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 username

    def 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:
            return
        phone_num = self.cleaned_data.get('username',None)
        sms_code = self.cleaned_data.get('sms_code', None)
        #注册验证码存入redis中
        return data

    def do_register(self,request):
        #执行注册
        data = self.cleaned_data
        version = 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,profile
        except 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 = result
            data = {
                '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')
]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/917565.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

快速了解Memcached

快速了解Memcached 官方定义 Memcached 是一个高性能的分布式内存对象缓存系统,用于减轻数据库负载,通过在内存中缓存数据和对象来提高动态 web 应用程序的响应速度。 主要特点 简单高效:其设计理念就是简单,易于部署和使用。它是…

【Android、IOS、Flutter、鸿蒙、ReactNative 】启动页

Android 设置启动页 自定义 splash.xml 通过themes.xml配置启动页背景图 IOS 设置启动页 LaunchScreen.storyboard 设置为启动页 storyboard页面绘制 Assets.xcassets 目录下导入图片 AppLogo Flutter 设置启动页 Flutter Android 设置启动页 自定义 launch_background.xm…

【插件】多断言 插件pytest-assume

背景 assert 断言一旦失败,后续的断言不能被执行 有个插件,pytest-assume的插件,可以提供多断言的方式 安装 pip3 install pytest-assume用法 pytest.assume(表达式,f’提示message’) pytest.assume(表达式,f‘提示message’) pytest.ass…

DDRPHY数字IC后端设计实现系列专题之数字后端floorplanpowerplan设计

3.2.3 特殊单元的布局 布图阶段除了布置 I/O 单元和宏单元,在 28nm 制程工艺时,还需要处理两种特 殊的物理单元,Endcap 和 Tapcell。 DDRPHY数字IC后端设计实现系列专题之后端设计导入,IO Ring设计 (1)拐…

Java 全栈知识体系

包含: Java 基础, Java 部分源码, JVM, Spring, Spring Boot, Spring Cloud, 数据库原理, MySQL, ElasticSearch, MongoDB, Docker, k8s, CI&CD, Linux, DevOps, 分布式, 中间件, 开发工具, Git, IDE, 源码阅读,读书笔记, 开源项目...

【Docker系列】如何在 Docker 环境中部署和运行 One API

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

录的视频怎么消除杂音?从录制到后期的杂音消除攻略

在录制视频时,杂音往往是一个令人头疼的问题。无论是环境噪音、设备噪音还是电磁干扰,杂音的存在都会极大地影响视频的听觉体验。录的视频怎么消除杂音?通过一些前期准备和后期处理技巧,我们可以有效地消除这些杂音,提…

微信小程序:vant组件库安装步骤

前言:在微信小程序中引用vant组件报错,提示路径不存在,这很有可能是因为没有安装构建vant组件库导致。下面是我整理的安装vant组件库的步骤: 第一步:安装node.js(执行完第一步请重启小程序) 具体步骤请看链接:node.js…

蓝桥杯-洛谷刷题-day3(C++)

目录 1.忽略回车的字符串输入 i.getline() ii.逐个字符的识别再输入 2.获取绝对值abs() 3.做题时的误区 4.多个变量的某一个到达判断条件 i.max() 5.[NOIP2016 提高组] 玩具谜题 i.代码 6.逻辑上的圆圈 i.有限个数n的数组 7.数组的定义 i.动态数组 1.忽略回车的字符串输…

Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别

Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别 keyword 与 text 区别term 查询match 查询match_phrase 查询match_phrase_prefix 查询写在最后 在讲述 es 查询时 term、match、match_phrase、match_phrase_prefix 的区别之前,先来了…

Restful API接⼝简介及为什么要进⾏接⼝压测

一、RESTful API简介 在现代Web开发中,RESTful API已经成为一种标准的设计模式,用于构建和交互网络应用程序。本文将详细介绍RESTful API的基本概念、特点以及如何使用它来设计高效的API接口。 1. 基于协议 HTTP 或 HTTPS RESTful API通常使用HTTP&am…

Android Studio 控制台输出的中文显示乱码

1. Android Studio 控制台输出的中文显示乱码 1.1. 问题 安卓在调试阶段,需要查看app运行时的输出信息、出错提示信息。乱码,会极大的阻碍开发者前进的信心,不能及时的根据提示信息定位问题,因此我们需要查看没有乱码的打印信息。…

前端无感刷新token

摘要: Axios 无感知刷新令牌是一种在前端应用中实现自动刷新访问令牌(access token)的技术,确保用户在进行 API 请求时不会因为令牌过期而中断操作 目录概览 XMLHttpRequestAxiosFetch APIJQuni.request注意事项: 访问…

ubuntu固定ip

根据自己的VMware中的网关信息和ip信息设置。 然后进入到ubuntu虚拟机的网络设置目录 cd /etc/netplan nano 01-network-manager-all.yaml根据自己的ip来设置!](https://i-blog.csdnimg.cn/direct/f0be245ced5143618c059d6f0734ed81.jpeg#pic_center) 应用你的设置 sudo ne…

阮一峰科技爱好者周刊(第 325 期)推荐工具:一个基于 Next.js 的博客和 CMS 系统

近期,阮一峰在科技爱好者周刊第 325 期中推荐了一款开源工具——ReactPress,ReactPress一个基于 Next.js 的博客和 CMS 系统,可查看 demo站点。(fecommunity 投稿) ReactPress:一款值得推荐的开源发布平台 …

DevOps工程技术价值流:打造卓越项目协作的优化宝典

一、引言 解锁项目协作的无限潜力,覆盖全链路实现流畅高效。 在当今瞬息万变的商业环境中,项目协作的效率和效果直接关系到企业的竞争力和市场响应速度。DevOps工程技术价值流中的项目协作优化,不仅是技术层面的革新,更是团队协…

如何从头开始构建神经网络?(附教程)

随着流行的深度学习框架的出现,如 TensorFlow、Keras、PyTorch 以及其他类似库,学习神经网络对于新手来说变得更加便捷。虽然这些框架可以让你在几分钟内解决最复杂的计算任务,但它们并不要求你理解背后所有需求的核心概念和直觉。如果你知道…

[flask][html]如何取消marker伪元素

【背景】 flask做项目时,导航栏默认出现小圆点,很难看,希望能够去除。 【分析】 前端查看后,发现是自动生成的伪元素::marker。 【方法】 找到相应的标签,我的情况是li,追加style。 style="list-style: none;"完整li部分: <li class="</

02-分布式对象存储设计原理

02-分布式对象存储设计原理 保存图片、音视频等大文件就是对象存储&#xff1a; 很好的大文件读写性能 还可通过水平扩展实现近乎无限容量 并兼顾服务高可用、数据高可靠 对象存储“全能”&#xff0c;主要因为&#xff0c;对象存储是原生分布式存储系统&#xff0c;相比MySQL、…

【论文复现】STM32设计的物联网智能鱼缸

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀STM32设计的物联网智能鱼缸 【1】项目功能介绍【2】设计需求总结【3】项目硬件模块组成 1.2 设计思路【1】整体设计思路【2】ESP8266工作模式…