1.使用以下命令生成用户表
makemigrations
makemigrat
2. 新建views.py视图
from django.contrib.auth.models import User
from rest_framework.generics import CreateAPIView
from rest_framework.views import APIView
from rest_framework.response import Response
from . import serializers
class RegisterView(CreateAPIView):
"""
注册接口
"""
serializer_class = serializers.RegisterSerializer
# 如果某个视图中, 没有获取信息的接口, 那么可以不用指定queryset类属性
class UsernamevalidateView(APIView):
"""
校验用户名
"""
def get(self, request, username):
data_dict = {
"username": username,
"count": User.objects.filter(username=username).count()
}
return Response(data_dict)
class EmailValidateView(APIView):
"""
校验邮箱
"""
def get(self, request, email):
data_dict = {
"email": email,
"count": User.objects.filter(email=email).count()
}
return Response(data_dict)
3. 新建urls.py
#!/usr/bin/env python
# encoding: utf-8
"""
@author: 拾壹
@software: PyCharm
@file: urls.py
@time: 2021/10/5 12:20
"""
from django.urls import path, re_path
from rest_framework_jwt.views import obtain_jwt_token
from . import views
urlpatterns = [
path('login/', obtain_jwt_token),
path('register/', views.RegisterView.as_view()),
re_path(r'^(?Pw{6,20})/count/$',
views.UsernamevalidateView.as_view(), name='check_username'),
re_path(r'^(?P[A-Za-z0-9]+@[a-zA-Z0-9]+.[a-zA-Z0-9_-]+)/count/$',
views.EmailValidateView.as_view(), name='check_email'),
]
4. 新建序列化器类serializer.py
#!/usr/bin/env python
# encoding: utf-8
"""
@author: 拾壹
@software: PyCharm
@file: serializers.py.py
@time: 2021/10/5 12:40
"""
from django.contrib.auth.models import User
from rest_framework.validators import Uniquevalidator
from rest_framework import serializers
from rest_framework_jwt.utils import api_settings
class RegisterSerializer(serializers.ModelSerializer):
password_confirm = serializers.CharField(label='确认密码', help_text='确认密码',
write_only=True, min_length=6, max_length=20,
error_messages={
'min_length': '仅允许6-20个字符的密码',
'max_length': '仅允许6-20个字符的密码',
})
token = serializers.CharField(label='生成的token', help_text='生成的token',
read_only=True)
class meta:
model = User
fields = ('id', 'username', 'password', 'email', 'token', 'password_/confirm/i')
# model指定的模型中没有的字段, 不能在extra_kwargs中来定义
extra_kwargs = {
'username': {
'label': '用户名',
'help_text': '用户名',
'min_length': 6,
'max_length': 20,
'error_messages': {
'min_length': '仅允许6-20个字符的用户名',
'max_length': '仅允许6-20个字符的用户名',
}
},
'email': {
'label': '邮箱',
'help_text': '邮箱',
'write_only': True,
'required': True,
# 添加邮箱重复校验
'validators': [Uniquevalidator(queryset=User.objects.all(), message='此邮箱已注册')],
},
'password': {
'label': '密码',
'help_text': '密码',
'write_only': True,
'min_length': 6,
'max_length': 20,
'error_messages': {
'min_length': '仅允许6-20个字符的密码',
'max_length': '仅允许6-20个字符的密码',
}
},
}
def validate(self, attrs):
password = attrs.get('password')
password_confirm = attrs.get('password_/confirm/i')
if password != password_/confirm/i:
raise serializers.ValidationError("两次输入的密码不一致!")
return attrs
def create(self, validated_data):
validated_data.pop('password_/confirm/i')
# 可以使用create_user方法来创建用户, 会对密码进行加密
user = User.objects.create_user(**validated_data)
# 生成token ?
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
user.token = token
return user
5. 在utils下新建自定义token登录返回值
jwt_handler.py文件
# -*- coding: utf-8 -*-
def jwt_response_payload_handler(token, user=None, request=None):
"""
对返回的数据进行重写
添加用户的信息
:param token:
:param user:
:param request:
:return:
"""
return {
'token': token,
'user_id': user.id,
'username': user.username
}
6.在全局settings下设置授权信息,授权类注释了,则不需要登录
REST_frameWORK = {
# 默认响应渲染类
'DEFAULT_RENDERER_CLASSES': (
# json渲染器为第一优先级
'rest_framework.renderers.JSONRenderer',
# 可浏览的API渲染器为第二优先级,不需要则取消
'rest_framework.renderers.BrowsableAPIRenderer',
),
# # django_filters.rest_framework.backends.DjangoFilterBackend
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend',
'rest_framework.filters.OrderingFilter'
],
# DEFAULT_PAGINATION_CLASS全局指定分页引擎类
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'DEFAULT_PAGINATION_CLASS': 'utils.pagination.ManualPageNumberPagination',
# 一定要指定, 每一页获取的条数
'PAGE_SIZE': 10,
# 指定用于支持coreapi的Schema
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
# 1. 指定认证类(指定的是认证的方式)
'DEFAULT_AUTHENTICATION_CLASSES': [
# 指定使用JWT Token认证
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
# DRF框架默认情况下, 使用的是用户会话认证
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
],
#
# 2. 授权类(指定的是认证成功之后, 能干嘛!)
'DEFAULT_PERMISSION_CLASSES': [
# DRF框架默认的权限为AllowAny(允许所有用户来访问)
'rest_framework.permissions.IsAuthenticated',
],
}
JWT_AUTH = {
# 默认token的过期时间为5分钟, 可以指定过期时间为1天
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
# 修改token值的前缀
# 前端在传递token值时, Authorization作为key, 值为:token前缀 token
# 'JWT_AUTH_HEADER_PREFIX': 'Bearer',
# 指定返回前端数据的处理函数
'JWT_RESPONSE_PAYLOAD_HANDLER': 'utils.jwt_handler.jwt_response_payload_handler',
}
7.全局路由下配置路由信息
urlpatterns = [
path('docs/', include_docs_urls(title='测试平台开发接口文档')),
path('', include('apps.users.urls')),
]



