📜  多用户 django rest 框架 - Python (1)

📅  最后修改于: 2023-12-03 14:51:40.817000             🧑  作者: Mango

多用户 Django REST 框架 - Python

介绍

在使用Django REST框架构建API时,我们常常需要提供多用户(用户身份验证)的API,以确保只有授权用户才能访问敏感数据。

在这篇文章中,我们将了解如何使用Django REST框架开发多用户API,并让您了解所有必需的部分,以便能用Python编写一个安全有效的多用户API。

设计

我们设计一个简单的多用户API,它能让注册用户在我们服务中创建和查看他们的图书清单。此API需要以下功能:

  • 用户身份验证
  • 列出所有图书清单
  • 创建一个新的图书清单
  • 用户只能查看和修改他们自己的清单
  • 允许用户用书名或作者名搜索书籍
安装

建立虚拟环境

首先,我们需要为我们的项目设置一个Python虚拟环境。在终端中使用以下命令:

python3 -m venv env

这将在项目文件夹中创建一个名为'env'的虚拟环境。

要激活虚拟环境,可以使用以下命令:

source env/bin/activate

安装 Django 和 Django REST 框架

在虚拟环境中使用以下命令安装Django:

pip install django

在我们的项目中,我们将使用Django REST框架构建API,所以接下来我们要安装rest_framework:

pip install djangorestframework
模型

我们需要创建两个数据库表:一个用于用户身份验证,另一个用于存储用户的图书清单信息。在我们的项目中,我们将使用Django默认的User模型来创建用户,然后创建一个BookList模型来存储用户的图书清单。

打开项目文件夹中的"settings.py"文件,并添加以下内容:

# settings.py

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

    'rest_framework',
    'booklist',
]

AUTH_USER_MODEL = 'auth.User'

在项目文件夹中,创建一个"booklist"文件夹,并创建一个名为"models.py"的文件,然后添加以下代码:

# models.py

from django.db import models
from django.contrib.auth.models import User

class BookList(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    description = models.TextField()
    isbn_number = models.CharField(max_length=100)
    date_added = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['date_added']

    def __str__(self):
        return self.title

以上模型定义了一个BookList模型,存储了作者名、书名、描述、ISBN、日期添加等有关图书清单数据的信息。ForeignKey关联到User模型,以确保每个创建的清单属于唯一的用户。

执行以下命令创建我们的数据库表:

python manage.py migrate
REST 框架

接下来,我们需要设置Django REST框架。在我们的项目中,我们将使用Django REST框架缺省的认证策略,即TokenAuthentication。

在项目文件夹的"settings.py"文件中,打开REST框架的用户认证的设置:

# settings.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],

    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],
}

在上面的代码中,我们设置了默认的权限类Permission和认证类Authentication,以触发REST框架的身份验证。TokenAuthentication需要我们在视图中手动调用。

序列化

在我们的API定义中,客户端将JSON格式的数据POST到API中。在我们的视图处理数据之前,我们需要验证客户端发送的数据是有效的,并且已将其转换为模型实例。

为了实现这个目标,我们要使用Django REST框架提供的序列化功能。这些序列化器允许我们将复杂的模型对象转换为简单的Python类型(例如字典,列表等),并将反序列化客户端提交的数据。

我们将在"booklist"文件夹中创建一个文件名为"serializers.py"的文件,并将以下代码添加到其中:

# serializers.py

from rest_framework import serializers
from .models import BookList

class BookListSerializer(serializers.ModelSerializer):
    class Meta:
        model = BookList
        fields = ['title', 'author', 'description', 'isbn_number']

上面的代码定义了一个BookListSerializer序列化器,将BookList模型转换为一个简单的Python类型。在这种情况下,我们选择将"title","author","description"和"isbn_number"作为序列化器输出的字段。

视图

在我们的API中,我们需要创建以下四个视图:

  1. 列出所有图书清单视图
  2. 创建新的图书清单视图
  3. 查看用户单个图书清单视图
  4. 修改用户单个图书清单视图

打开"booklist"文件夹中的"views.py"文件,并添加以下代码:

# views.py

from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from .models import BookList
from .serializers import BookListSerializer

class BookListList(generics.ListCreateAPIView):
    permission_classes = (IsAuthenticated,)

    def get_queryset(self):
        queryset = BookList.objects.filter(user=self.request.user)
        title = self.request.query_params.get('title', None)
        author = self.request.query_params.get('author', None)
        if title and author:
            queryset = queryset.filter(title=title, author=author)
        elif title:
            queryset = queryset.filter(title=title)
        elif author:
            queryset = queryset.filter(author=author)
        return queryset

    serializer_class = BookListSerializer

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

class BookListDetail(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (IsAuthenticated,)

    def get_queryset(self):
        queryset = BookList.objects.filter(user=self.request.user)
        return queryset

    serializer_class = BookListSerializer

上述代码定义了两个视图:BookListList和BookListDetail。BookListList视图返回用户的所有图书清单,并可根据书名或作者名进行筛选。BookListDetail视图返回单个图书清单,该清单属于当前用户,客户端也可以更新或删除该清单。

URL配置

现在我们已经定义了我们的视图,我们需要将它们添加到项目的urls.py文件中。

打开项目文件夹中的"urls.py"文件,并添加以下代码:

# urls.py

from django.urls import path, include
from rest_framework import routers
from rest_framework.authtoken.views import obtain_auth_token
from booklist import views

router = routers.DefaultRouter()

urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls')),
    path('api-token-auth/', obtain_auth_token, name='api_token_auth'),
    path('booklist/', views.BookListList.as_view()),
    path('booklist/<int:pk>/', views.BookListDetail.as_view()),
]
测试

现在我们已经完成了整个API的构建,最后我们需要测试和确认它是否能够正常运行。

在虚拟环境中运行以下命令以启动该应用程序:

python manage.py runserver

使用PostMan等模拟客户端,测试我们的API:

用户注册

向"/rest-auth/registration/"发送POST请求,发送以下数据:

{
    "username": "test_user",
    "email": "test_user@example.com",
    "password1": "test_user_password",
    "password2": "test_user_password"
}

登录并获取Token

向"/api-token-auth/"发送POST请求,并使用用户名和密码作为请求参数。如果认证成功,你将收到一个如下的JSON响应:

{
    "token": "f3d92c91171a6c9dfc1d6a06f6d0f2efc49fa66a"
}

列出所有图书清单

使用刚刚获取的Token做为请求Header,向"/booklist/"发送GET请求。

创建新的图书清单

使用刚刚获取的Token和以下数据向"/booklist/"发送POST请求:

{
    "title": "test book",
    "author": "test author",
    "description": "test description",
    "isbn_number": "test isbn_number"
}

查看用户单个图书清单

使用刚刚获取的Token做为请求Header,向"/booklist/int:pk/"发送GET请求。

修改用户单个图书清单

使用刚刚获取的Token和以下数据向"/booklist/int:pk/"发送PUT请求:

{
    "title": "test book updated",
    "author": "test author",
    "description": "test description",
    "isbn_number": "test isbn_number"
}

删除用户单个图书清单

使用刚刚获取的Token做为请求Header,向"/booklist/int:pk/"发送DELETE请求。

总结

在本文中,我们学习了如何使用Django REST框架构建多用户API,包括设置认证和管理权限,序列化数据和定义视图。最后我们使用PostMan等工具进行API测试,确保API正在按预期工作。

希望这篇文章对开发者们有所帮助!