Django提供了一个用户模型User,我们将在这个基础上设计用户管理模块。当然也可以自己设计,涉及到的认证和权限,请查看我的另一篇文章:https://blog.csdn.net/weixin_43431593/article/details/108930697
File->New Project->选中Django,输入工程名称TestingPlatform直接创建。(专业版)
也可创建工程后手动创建,相关文章请查看本系列内容。(社区版)
1、登录mysql,创建数据库testing_platform:
CREATE DATABASE testing_platform CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;2、安装mysqlclient并连接mysql:
官网:https://pypi.org/project/mysqlclient/
官方描述:
Windows Building mysqlclient on Windows is very hard. But there are some binary wheels you can install easily.也就是在windows安装该模块比较困难,可能需要使用wheel安装:
虽然官方描述得比较艰难,但是,如果python版本正确的情况下(3.6、3.7、3.8),直接安装也是可以的:
pip install mysqlclient3、连接数据库:
DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': BASE_DIR / 'db.sqlite3', # } 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'testing_platform', 'USER': 'root', 'PASSWORD': 'yeqinfang', # 'HOST': '192.168.31.201', 'HOST': '10.12.1.199', 'PORT': '3306', } }如上,虽然没有创建应用,他也可以生成表,这些表就是django自带的表。我们将基于此进行用户管理的开发。
如上,在工程文件下创建,与全局配置的文件夹平级。右键apps,将其标记为source root。
我想把所有应用放到apps文件夹,因为放在外面的话,后续应用会很多,不好管理。鉴于django是根据path路径来查找应用的,只要把路径添加到全局settings.py中即可:
sys.path.append(os.path.join(BASE_DIR, 'apps'))创建user后,再把这个user应用拖动到apps中,不勾选任何选项。
先进行安装:
pip install djangorestframework安装后,需要把它当做应用注册。
JWT 是一个开放标准(RFC 7519),它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。该信息可以被验证和信任,因为它是数字签名的。JWTS可以使用秘密(使用HMAC算法)或公钥/私钥对使用RSA或ECDSA来签名。
因为流行,所以我们先安装它,然后使用它:
pip install djangorestframework-jwt1、在user下创建序列化器serializers.py 2、基于django.contrib.auth.models的User模型编写序列化器:
from rest_framework import serializers from rest_framework.validators import UniqueValidator from django.contrib.auth.models import User from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler class RegisterSerializer(serializers.ModelSerializer): password_confirm = serializers.CharField(label='确认密码', help_text='确认密码', min_length=6, max_length=20, write_only=True, error_messages={ 'min_length': '仅允许6~20个字符的确认密码', 'max_length': '仅允许6~20个字符的确认密码', }) token = serializers.CharField(label='生成token', read_only=True) class Meta: model = User fields = ('id', 'username', 'password', 'email', 'password_confirm', 'token') 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): if attrs.get('password') != attrs.get('password_confirm'): raise serializers.ValidationError('密码与确认密码不一致') return attrs def create(self, validated_data): validated_data.pop('password_confirm') # 创建user模型对象 user = User.objects.create_user(**validated_data) # 创建token payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) user.token = token return user3、在视图中编写接口:
from django.contrib.auth.models import User from rest_framework.views import APIView from rest_framework.generics import CreateAPIView from rest_framework.response import Response from .serializers import RegisterSerializer class UserView(CreateAPIView): serializer_class = RegisterSerializer # def post(self, request, *args, **kwargs): # serializer = RegisterSerializer(data=request.data) # serializer.is_valid(raise_exception=True) # serializer.save() # # return Response(serializer.data, status=status.HTTP_201_CREATED) class UsernameIsExistedView(APIView): def get(self, request, username): count = User.objects.filter(username=username).count() # count = user.count() one_dict = { 'username': username, 'count': count } return Response(one_dict) class EmailIsExistedView(APIView): def get(self, request, email): count = User.objects.filter(email=email).count() # count = user.count() one_dict = { 'email': email, 'count': count } return Response(one_dict)在user文件夹,新建一个urls,如:
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.UserView.as_view()), re_path(r'^(?P<username>\w{6,20})/count/$', views.UsernameIsExistedView.as_view()), re_path(r'^(?P<email>[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+)/count/$', views.EmailIsExistedView.as_view()), ]在主路由中引用,举个例子:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('user/', include('user.urls')), ]请求注册: 请求登录接口: 如上,说明注册接口和登录接口都已经实现,并且返回了JWT格式的token。
安装依赖组件coreapi:
pip install coreapisettings.py文件配置:
REST_FRAMEWORK = { 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema' }主路由添加并使用:
from rest_framework.documentation import include_docs_urls urlpatterns = [ path('admin/', admin.site.urls), path('docs/', include_docs_urls(title='测试平台接口文档', description='xxx描述')), path('user/', include('user.urls')), ]再次运行后,打开界面如下:
上面的请求,并没有配置认证,因此,在工程目录下创建utils安装包目录,并写入:
def jwt_response_payload_handler(token, user=None, request=None): return { 'user_id': user.id, 'username': user.username, 'token': token }该文件夹用于存储常用工具。
需要在settings配置:
REST_FRAMEWORK = { 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema', 'DEFAULT_AUTHENTICATION_CLASSES': [ # 指定使用JWT token认证方式 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', # 会话认证 'rest_framework.authentication.SessionAuthentication', # 基本认证(用户名和密码认证) 'rest_framework.authentication.BasicAuthentication', ], } # 在全局配置JWT_AUTH中,可以覆盖JWT相关的参数 JWT_AUTH = { # 指定处理登录接口响应数据的函数 'JWT_RESPONSE_PAYLOAD_HANDLER': 'utils.jwt_handle.jwt_response_payload_handler', # 前端用户访问一些需要认证之后的接口,那么默认需要在请求头中携带参数, # 请求key为Authorization,值为前缀 + 空格 + token值,如:JWT xxxssdhdsohsoshsohs # 可以指定token过期时间,默认为5分钟 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), # 指定前端传递token值的前缀 # 'JWT_AUTH_HEADER_PREFIX': 'Bearer', }先进行配置,后续我们写其他模块的时候,将会进行使用。接着运行起来,没有问题即可。
