Django让web开发更简单(八):设计用户模块

设计一个用户管理模块

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 mysqlclient

3、连接数据库:

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',
    }
}

执行迁移

python manage.py makemigrations
python manage.py migrate

在这里插入图片描述
如上,虽然没有创建应用,他也可以生成表,这些表就是django自带的表。我们将基于此进行用户管理的开发。

新建apps文件夹

在这里插入图片描述如上,在工程文件下创建,与全局配置的文件夹平级。右键apps,将其标记为source root。

我想把所有应用放到apps文件夹,因为放在外面的话,后续应用会很多,不好管理。鉴于django是根据path路径来查找应用的,只要把路径添加到全局settings.py中即可:

sys.path.append(os.path.join(BASE_DIR, 'apps'))

创建应用

django-admin startapp user

创建user后,再把这个user应用拖动到apps中,不勾选任何选项。
在这里插入图片描述

注册应用

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'user',
]

注册rest_framework

先进行安装:

pip install djangorestframework

安装后,需要把它当做应用注册。

使用JWT认证方式

JWT 是一个开放标准(RFC 7519),它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。该信息可以被验证和信任,因为它是数字签名的。JWTS可以使用秘密(使用HMAC算法)或公钥/私钥对使用RSA或ECDSA来签名。

因为流行,所以我们先安装它,然后使用它:

pip install djangorestframework-jwt

编写用户管理接口

1、在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 user

3、在视图中编写接口:

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')),
]

运行工程

python manage.py runserver

请求注册:
在这里插入图片描述
请求登录接口:
在这里插入图片描述
如上,说明注册接口和登录接口都已经实现,并且返回了JWT格式的token。

接口文档

安装依赖组件coreapi:

pip install coreapi

settings.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')),
]

再次运行后,打开界面如下:
在这里插入图片描述

JWT设置

上面的请求,并没有配置认证,因此,在工程目录下创建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',
}

先进行配置,后续我们写其他模块的时候,将会进行使用。接着运行起来,没有问题即可。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lion King

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值