使用Django REST Framework构建基于权限的用户管理系统

摘要

本教程将指导您如何使用Django REST Framework构建一个基于权限的用户管理系统。Django REST Framework是一个功能强大的Web API框架,用于构建易于维护和扩展的API。我将从创建项目开始,逐步讲解如何设计数据模型、序列化器、视图、路由、数据库迁移以及使用APIfox测试API。

1.创建项目与应用

1.首先,我们需要安装Django和Django REST Framework。Django是一个高级的Python Web框架,它可以帮助我们快速构建安全、可维护的Web应用。Django REST Framework是基于Django的一个扩展,它让我们能够更轻松地构建Web API。

安装Django和Django REST Framework:

pip install django djangorestframework

2.接下来,我们创建一个名为UserManagementSystem的Django项目,并在其中创建一个名为user_management的应用。

创建项目:

django-admin startproject UserManagementSystem
cd UserManagementSystem

3.创建应用:

python manage.py startapp user_management

2. 安装并配置Simple JWT

为了支持JWT(JSON Web Token)身份验证,我们需要安装djangorestframework-simplejwt:

pip install djangorestframework-simplejwt

接下来,在UserManagementSystem/settings.py中进行以下配置:

  • 将user_management应用添加到INSTALLED_APPS:
INSTALLED_APPS = [
    # ...
    'rest_framework',
    'user_management',
]
  • 添加Django REST Framework和Simple JWT相关设置:
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
}
#Simple JWT settingsfrom datetime import timedelta

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': True,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,

    'AUTH_HEADER_TYPES': ('Bearer',),
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',

    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}
  • 设置AUTH_USER_MODEL。在Django中,默认用户模型是auth.User。当您需要定制用户模型时,需创建一个自定义用户模型(如本项目中的User模型),并继承自AbstractUser。要让Django使用自定义用户模型,需要在settings.py文件中设置AUTH_USER_MODEL。这里的AUTH_USER_MODEL = 'user_management.User’告诉Django使用user_management应用中的User模型作为默认用户模型。设置AUTH_USER_MODEL后,Django将使用自定义用户模型处理用户和认证相关功能。
AUTH_USER_MODEL = 'user_management.User'

3. 设计数据模型、序列化器、视图和路由

接下来,我们需要设计用户数据模型、序列化器、视图和路由。这部分的代码可以参考上文中的示例代码,逐个文件创建并添加相应的代码。

  • 在user_management/models.py中创建用户模型。
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    ROLE_CHOICES=(
      ('admin','管理员'),
      ('normal','普通用户')

    )
    role=models.CharField(max_length=10,choices=ROLE_CHOICES,default='normal',verbose_name='角色')

    class Meta:
        verbose_name='用户'
        verbose_name_plural=verbose_name
  • 在user_management/serializers.py中创建用户序列化器。
from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'password', 'email', 'role']  # 保留自定义字段列表
        extra_kwargs = {
            'password': {'write_only': True}
        }
  • 在user_management/views.py中创建视图。
from rest_framework import viewsets, status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404
from .serializers import UserSerializer
from .models import User


# 自定义令牌获取序列化器,继承自TokenObtainPairSerializer
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    # 设置用户名字段为'username'
    username_field = 'username'

    # 重写validate方法
    def validate(self, attrs):
        # 调用父类的validate方法,存入登录用户的数据
        data = super().validate(attrs)
        # 获取当前用户
        user = self.user
        # 向返回的数据中添加用户名字段
        data['username'] = user.username
        return data

# 自定义令牌获取视图,继承自TokenObtainPairView
class CustomTokenObtainPairView(TokenObtainPairView):
    # 设置序列化器类为自定义的CustomTokenObtainPairSerializer
    serializer_class = CustomTokenObtainPairSerializer

# 用户视图集
class UserViewSet(viewsets.ModelViewSet):
    # 指定序列化器类
    serializer_class = UserSerializer
    # 指定权限类,要求用户认证
    permission_classes = [IsAuthenticated]

    # 定义获取查询集的方法
    def get_queryset(self):
        # 如果请求用户是管理员,返回所有用户
        if self.request.user.role == 'admin':
            return User.objects.all()
        else:
            # 否则,只返回当前用户
            return User.objects.filter(id=self.request.user.id)

    # 定义处理用户列表请求的方法
    def list(self, request):
        users = self.get_queryset()  # 获取查询集
        paginator = Paginator(users, 10)  # 使用分页器,每页10个用户
        page_number = request.GET.get('page')  # 获取页码
        page_obj = paginator.get_page(page_number)  # 获取当前页对象
        serializer = self.get_serializer(page_obj, many=True)  # 序列化当前页对象
        return Response(serializer.data)  # 返回序列化数据

    # 定义处理获取单个用户请求的方法
    def retrieve(self, request, pk=None):
        # 如果请求用户不是管理员且请求的用户ID与当前用户ID不匹配,则拒绝请求
        if not request.user.role == 'admin' and str(request.user.id) != pk:
            return Response({'detail': 'You do not have permission to perform this action.'}, status=status.HTTP_403_FORBIDDEN)
        user = get_object_or_404(self.get_queryset(), pk=pk)  # 获取指定用户对象
        serializer = self.get_serializer(user)  # 序列化用户对象
        return Response(serializer.data)  # 返回序列化数据

    # 定义处理删除用户请求的方法
    def destroy(self, request, pk=None):
        # 如果请求用户不是管理员,拒绝请求
        if not request.user.role == 'admin':
            return Response({'detail': 'You are not authorized to perform this action.'}, status=status.HTTP_403_FORBIDDEN)
        user = get_object_or_404(self.get_queryset(), pk=pk)  # 获取指定用户对象
        user.delete()  # 删除用户
        return Response(status=status.HTTP_204_NO_CONTENT)  # 返回204状态码表示删除成功

    # 定义处理创建用户请求的方法
    def create(self, request):
        # 如果请求用户不是管理员,拒绝请求
        if not request.user.role == 'admin':
            return Response({'detail': 'You are not authorized to perform this action.'}, status=status.HTTP_403_FORBIDDEN)
        data = request.data.copy()  # 复制请求数据
        data['role'] = 'normal'  # 设置新用户角色为普通用户
        serializer = self.get_serializer(data=data)  # 创建序列化器实例
        serializer.is_valid(raise_exception=True)  # 验证数据
        serializer.save()  # 保存用户
        return Response(serializer.data, status=status.HTTP_201_CREATED)  # 返回序列化数据

    # 定义处理更新用户请求的方法
    def update(self, request, pk=None):
        # 如果请求用户不是管理员且请求的用户ID与当前用户ID不匹配,则拒绝请求
        if not request.user.role == 'admin' and str(request.user.id) != pk:
            return Response({'detail': 'You do not have permission to perform this action.'}, status=status.HTTP_403_FORBIDDEN)
        user = get_object_or_404(self.get_queryset(), pk=pk)  # 获取指定用户对象
        data = request.data.copy()  # 复制请求数据
        data['role'] = user.role  # 不允许修改用户的角色
        serializer = self.get_serializer(user, data=data)  # 创建序列化器实例
        serializer.is_valid(raise_exception=True)  # 验证数据
        serializer.save()  # 更新用户
        return Response(serializer.data, status=status.HTTP_200_OK)  # 返回序列化数据
  • 在user_management/urls.py中创建路由。
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from user_management.views import CustomTokenObtainPairView, UserViewSet


router = routers.DefaultRouter()
router.register(r'users', UserViewSet, basename='user')


urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/token/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/', include(router.urls)),

]

4.数据库迁移

在定义了数据模型后,我们需要将其映射到数据库。执行以下命令进行数据库迁移:

python manage.py makemigrations
python manage.py migrate

5.创建一个管理员账号

python manage.py shell 
from user_management.models import User

# 创建具有 admin 角色的用户
user = User.objects.create_user(username='admin', password='123', role='admin')

6.在本地启动Django项目:

python manage.py runserver

7.使用APIfox测试API

APIfox是一个功能强大的API测试工具。我们可以使用APIfox对我们创建的API进行测试。

  • 创建"获取令牌"接口:选择请求方法为"POST",输入请求URL为http://127.0.0.1:8000/api/token/。在"请求参数"中,添加username和password参数,分别填入您的用户名和密码。点击"发送",获取到访问令牌

(access_token)。
使用Django REST Framework构建基于权限的用户管理系统_第1张图片

  • 使用访问令牌调用其他API:在其他接口的"请求头"中添加键值对:Authorization: Bearer
    ,其中需要替换为实际的访问令牌。

使用Django REST Framework构建基于权限的用户管理系统_第2张图片

我们可以使用APIfox逐个运行测试用例,观察返回的结果。如果返回的数据和预期一致,说明我们的项目已经成功搭建完成。

总结

在本教程中,我们从头开始搭建了一个基于权限的用户管理系统。我们使用Django REST Framework构建了API,并引入了Simple JWT支持JWT身份验证。通过这个项目,您可以学习到Django REST Framework的基本使用方法和概念,以及如何利用API测试工具(如APIfox)进行API测试。
接下来,您可以进一步优化项目,例如优化视图和序列化器的代码,或者添加更多的功能。如果本文对您有所帮助,请记得关注作者。您的支持是我持续的动力!

你可能感兴趣的:(django,python,后端,restful)