Django drf使用Django自带的用户系统的注册功能

目录
  • 1.阅读Django自带用户系统源码
    • 1.1 阅读User类源码
    • 1.2 阅读AbstractUser类
  • 2.创建自己的User类
    • 2.1 创建验证器
    • 2.2 创建User类
  • 3.创建序列化类
  • 4.创建views类
  • 5.创建路由
  • 6.测试接口

在写登录功能的时候看着网上的视频学着做,然后看了源码的时候发现了一些有意思的功能,因此写这一篇笔记分享给大家.

1.阅读Django自带用户系统源码

1.1 阅读User类源码

系统自带的用户系统的models文件的位置\site-packages\django\contrib\auth\models.py,打开这个文件发现User类继承的是一个AbstractUser类,因此我们想要使用系统自带的用户系统,只要在models中重新写一个User类,也继承AbstractUser就可以了.

1.2 阅读AbstractUser类

阅读AbstractUser类,发现了其中的对username字段做的几个处理,第一个就是他添加了一个验证器validators,第二个增加了error_messages,当在我们往数据库中添加用户信息的时候,系统就会自动验证是否符合要求,如果不符合要求,就会返回一个字典,将对应字段的错误返回,这就是我想到的与其他博主所做的不同之处.

2.创建自己的User类

我想我的用户类中有mobile,username,email,password四个字段,我的需求:

mobile,username,email都是不能重复

验证这几个字段的格式

返回的errormessage为中文
因此我就想到了模仿系统自带的AbstractUser的写法:

2.1 创建验证器

这个验证器是其中主要是验证电话号码和邮箱的格式正误,因为其他的类也可能需要用到验证器,因此我就在项目的utils目录下创建了一个validator.py文件,用于专门存取验证器.
项目根目录\utils\validator.py代码:

# 验证电话号码是否有误
import re
from django.core.exceptions import ValidationError

# 对手机格式进行验证
class UnicodMobileValidator:
    def __call__(self, value):
        if not re.match(r"^1[3-9]\d{9}$", value):
             raise ValidationError("对不起,手机格式有误!")

# 对邮箱格式进行验证
class UnicodEmailValidator:
    def __call__(self, value):
        if not re.match(r"^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$", value):
             raise ValidationError("对不起,邮箱格式有误!")

2.2 创建User类

这里我继承了AbstractUser类,并且重写了其中的方法和属性.
user\models.py代码:

from datetime import timezone

from django.contrib.auth.validators import UnicodeUsernameValidator
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, AbstractUser

from qianxingtong_main.utils.validator import UnicodMobileValidator, UnicodEmailValidator

class User(AbstractUser):
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(
        ("username"),
        max_length=150,
        unique=True,
        help_text=(
            "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
        ),
        validators=[username_validator],
        error_messages={
            "unique": ("该用户名已经存在"),
        },
    )

    email = models.EmailField(("email address"), unique=True, validators=[UnicodEmailValidator()],error_messages={"unique": ("邮箱已经存在"),})
    mobile = models.CharField(max_length=15, unique=True, validators=[UnicodMobileValidator()],
                              error_messages={"unique": ("电话号码已经存在")}, verbose_name="手机号码")

    class Meta:
        db_table = "drf_user"
        verbose_name = "用户信息"
        verbose_name_plural = verbose_name

这里在迁移数据的时候可能会出现错误,其中错误的解决方法参考我写的笔记:https://www.jb51.net/article/275133.htm 的第三步

3.创建序列化类

user\serializers代码:

from django.contrib.auth.hashers import make_password
from rest_framework import serializers
from user.models import User
class UserSerializer(serializers.ModelSerializer):
    rpassword = serializers.CharField(required=True, write_only=True, help_text="确认密码")
    token = serializers.CharField(max_length=1024, read_only=True, help_text="token认证字符串")
    class Meta:
        model = User
        fields = ["id", "username", "email", "mobile", "password", "token", "rpassword"]
        # write_only:只写入数据库,
        extra_kwargs = {
            "mobile": {
                "write_only": True,
            },
            "email": {
                "write_only": True,
            },
            "id": {
                "read_only": True,
            },

        }

    def validate(self, attrs):
        """校验信息"""
        password = attrs.get("password")
        rpassword = attrs.get("rpassword")
        if password != rpassword:
            # 验证手机号码是否已经被注册
            raise serializers.ValidationError("对不起,确认密码与密码不一致!")
        return attrs

    def create(self, validated_data):
        """保存用户信息"""
        mobile = validated_data.get("mobile")
        username = validated_data.get("username")
        email = validated_data.get("email")

        validated_data.pop("rpassword")  # 移除不需要的数据
        # 对密码进行加密
        raw_password = validated_data.get("password")
        hash_password = make_password(raw_password)
        # 调用序列化器提供的create方法
        user = User.objects.create(
            mobile=mobile,
            username=username,
            password=hash_password,
            email=email
        )
        return user

这个代码就是我与其他的博主不同的地方,我看网上的up主就是把验证的代码写在validate中,但是这里存在的一个问题就是所有的错误都是统一一起打包返回,无法在前端中做对应字段的错误提示.

4.创建views类

user\views代码:

from rest_framework.generics import CreateAPIView
from user.models import User
from user.serializers import UserSerializer

# Create your views here.
class UserViewSets(CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

5.创建路由

6.测试接口

从测试结果就可以看出,针对不同的字段,会返回对应的错误,而不是一起返回的.

到此这篇关于Django drf使用Django自带的用户系统的注册功能 的文章就介绍到这了,更多相关Django drf用户系统注册内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Django框架之DRF 基于mixins来封装的视图详解

    基础视图 示例环境搭建:新建一个Django项目,连接Mysql数据库,配置路由.视图函数.序列化单独创建py文件 # 配置路由 from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^PublishView/', views.PublishView.as_vi

  • Django与DRF结合的全局异常处理方案详解

    目录 前言 实现的目标 DRF全局异常拦截的解决思路 Django异常处理方案 总结 前言 Django 和 DRF(django rest framawork) 的结合在 python 后台中经常出现的组合.对于异常的全局处理,我们系统能有一个统一的解决方案,在开发环境能看到比较全的异常堆栈,而在生产环境能更好的给用户一个友好的提示,本文旨在提出一个统一个全局异常处理方案,仅供参考使用. 实现的目标 如果没有 DRF,我们只需要在 Django 中加一个中间件就可以解决全局异常的处理问题,但是

  • Django实现drf搜索过滤和排序过滤

    前言 当我们需要对后台的数据进行过滤的时候,drf有两种,搜索过滤和排序过滤. 搜索过滤:比如我们想返回sex=1的,那么我们就可以从所有数据中进行筛选 排序过滤:比如我们想对价格进行升序排列,就可以使用排序过滤 搜索过滤 在实际的使用过程中十分简单,只需要在视图类中配置一个全局变量filter_backends,然后在search_fields确定需要通过哪个字段进行筛选 from rest_framework.filters import SearchFilter class CarView

  • DRF跨域后端解决之django-cors-headers的使用

    在使用django-rest-framework开发项目的时候我们总是避免不了跨域的问题,因为现在大多数的项目都是前后端分离,前后端项目部署在不同的web服务器上,因为我们是后端程序员,因此我要通过后端的程序实现跨域.当然如果前端框架是Vue的话,则可以代理服务实现跨域,我也就知道一点点,如果有兴趣,大家可以自行搜索哦. DRF后端实现跨域我们使用一个第三方扩展--- djangocorsheaders 安装 pip install django-cors-headers 注册 INSTALLE

  • Django DRF APIView源码运行流程详解

    首先写一个简单的drf接口 from rest_framework.views import APIView from rest_framework.response import Response # 基于drf写接口,cbv class DrfTest(APIView): def get(self, request,*args,**kwargs): print(type(request._request)) print(type(request)) print(request.POST) p

  • Django DRF认证组件流程实现原理详解

    视图函数中加上认证功能,流程见下图 import hashlib import time def get_random(name): md = hashlib.md5() md.update(bytes(str(time.time()),encoding='utf-8')) md.update(bytes(name,encoding='utf-8')) return md.hexdigest() from rest_framework.views import APIView class Log

  • Django drf请求模块源码解析

    DRF 框架,全称为 Django Rest Framework,是 Django 内置模块的扩展,用于创建标准化 RESTful API:它利用 ORM 映射数据库,并自定义序列化数据进行返回,多用于前后端分离项目 项目地址: https://github.com/encode/django-rest-framework 请求模块:request对象 源码入口 APIView类中dispatch方法中的:request=self.iniialize_request(*args, **kwarg

  • django DRF图片路径问题的解决方法

    前言 其实就是Django RESTful Framework,RESTful一种API的命名风格,主要因为前后端分离开发出现,前后端分离: 用户访问静态文件的服务器,数据全部由ajax请求给到,RESTful风格:数据应该是名词,而动词由HTTP的请求方式来体现,RESTful风格的API给前端返回 结果对象,无论什么请求方式 本文主要介绍了关于django DRF图片路径问题,下面话不多说了,来一起看看详细的介绍吧 问题描述: 为什么DRF中有时候返回的json中图片是带域名的,有时候是不带

  • Django DRF路由与扩展功能的实现

    一. 视图集与路由的使用 使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中: list() 提供一组数据 retrieve() 提供单个数据 create() 创建数据 update() 保存数据 destory() 删除数据 ViewSet视图集类不再实现get().post()等方法,而是实现动作 action 如 list() .create() 等. 视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上. 1. 常用的视图集父类 1.Vi

  • Django drf分页器的使用详解

    前言 当后台返回的数据过多时,我们就要配置分页器,比如一页最多只能展示10条等等,drf中默认配置了3个分页面 PageNumberPagination:基础分页器,性能略差 LimitOffsetPagination:偏移分页器 CursorPagination:游标分页器,性能强大 PageNumberPagination 基础分页器PageNumberPagination,数据量越大性能越差. 首先我们在app中创建一个pagination.py文件,然后自定义一个分页器类,继承自Page

随机推荐