📅  最后修改于: 2023-12-03 14:51:40.817000             🧑  作者: Mango
在使用Django REST框架构建API时,我们常常需要提供多用户(用户身份验证)的API,以确保只有授权用户才能访问敏感数据。
在这篇文章中,我们将了解如何使用Django REST框架开发多用户API,并让您了解所有必需的部分,以便能用Python编写一个安全有效的多用户API。
我们设计一个简单的多用户API,它能让注册用户在我们服务中创建和查看他们的图书清单。此API需要以下功能:
首先,我们需要为我们的项目设置一个Python虚拟环境。在终端中使用以下命令:
python3 -m venv env
这将在项目文件夹中创建一个名为'env'的虚拟环境。
要激活虚拟环境,可以使用以下命令:
source env/bin/activate
在虚拟环境中使用以下命令安装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
接下来,我们需要设置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中,我们需要创建以下四个视图:
打开"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视图返回单个图书清单,该清单属于当前用户,客户端也可以更新或删除该清单。
现在我们已经定义了我们的视图,我们需要将它们添加到项目的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"
}
向"/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正在按预期工作。
希望这篇文章对开发者们有所帮助!