DRF 即 Django REST framework,它是一个建立在 Django 基础之上的强大且灵活的工具包,用于构建 Web API(应用程序编程接口)。简单来说,它就像是一个“桥梁”,帮助我们在 Django 项目中更轻松地创建和管理与外部应用或客户端进行数据交互的接口。
要安装 DRF,首先需要确保你已经安装了 Python 和 Django。然后,使用 pip
(Python 包管理工具)来安装 DRF,在命令行中输入以下命令:
pip install djangorestframework
安装完成后,你可以通过以下命令来验证是否安装成功:
pip show djangorestframework
如果显示了 DRF 的相关信息,说明安装成功啦。
安装好 DRF 后,还需要对 Django 项目进行一些配置。
rest_framework
到 INSTALLED_APPS
打开 Django 项目的 settings.py
文件,在 INSTALLED_APPS
列表中添加 'rest_framework'
,如下所示:
INSTALLED_APPS = [
# ...
'rest_framework',
# ...
]
你可以在 settings.py
文件中添加一些全局的 DRF 设置,例如设置默认的认证类和权限类:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated'
]
}
以上配置表示默认使用会话认证和基本认证,并且只有经过认证的用户才能访问 API 接口。
打开命令行,进入你想要创建项目的目录,然后执行以下命令创建一个新的 Django 项目:
django-admin startproject drf_example
cd drf_example
在项目目录下,执行以下命令创建一个新的 Django 应用:
python manage.py startapp myapp
打开 myapp/models.py
文件,定义一个简单的模型,例如:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
def __str__(self):
return self.title
在 myapp
目录下创建一个 serializers.py
文件,编写一个序列化器来处理 Book
模型的数据:
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id', 'title', 'author']
打开 myapp/views.py
文件,编写一个简单的视图来处理 API 请求:
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
打开 drf_example/urls.py
文件,配置 URL 路由:
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from myapp.views import BookViewSet
router = DefaultRouter()
router.register(r'books', BookViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]
在命令行中执行以下命令来创建数据库表:
python manage.py makemigrations
python manage.py migrate
执行以下命令启动 Django 开发服务器:
python manage.py runserver
打开浏览器或使用工具(如 Postman)访问 http://127.0.0.1:8000/api/books/
,你应该能看到一个空的 JSON 列表(因为还没有添加任何书籍数据)。你还可以通过 POST 请求向该接口添加新的书籍数据,通过 GET 请求获取所有书籍数据,通过 PUT 或 PATCH 请求更新书籍数据,通过 DELETE 请求删除书籍数据等。这样,一个简单的 DRF 项目就完成啦!
user = {'name': 'Alice', 'age': 25}
,将其转换为 JSON 字符串 '{"name": "Alice", "age": 25}'
的过程就是序列化。'{"name": "Alice", "age": 25}'
转换为 Python 字典 {'name': 'Alice', 'age': 25}
的过程就是反序列化。在 Django REST Framework 中,我们可以通过继承 serializers.Serializer
类来定义自己的序列化器类。以下是一个简单的示例:
from rest_framework import serializers
class UserSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
age = serializers.IntegerField()
在这个示例中,我们定义了一个 UserSerializer
类,它包含两个字段:name
和 age
,分别使用 CharField
和 IntegerField
进行定义。
序列化数据的过程就是将 Python 对象转换为 JSON 等格式的过程。以下是一个序列化数据的示例:
from rest_framework import serializers
class UserSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
age = serializers.IntegerField()
user = {'name': 'Bob', 'age': 30}
serializer = UserSerializer(user)
print(serializer.data) # 输出: {'name': 'Bob', 'age': 30}
在这个示例中,我们创建了一个 UserSerializer
实例,并将一个包含用户信息的字典传递给它。然后通过 serializer.data
获取序列化后的数据。
反序列化数据的过程就是将 JSON 等格式的数据转换为 Python 对象的过程。以下是一个反序列化数据的示例:
from rest_framework import serializers
class UserSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
age = serializers.IntegerField()
data = {'name': 'Charlie', 'age': 35}
serializer = UserSerializer(data=data)
if serializer.is_valid():
print(serializer.validated_data) # 输出: {'name': 'Charlie', 'age': 35}
else:
print(serializer.errors)
在这个示例中,我们创建了一个 UserSerializer
实例,并将一个包含用户信息的字典作为数据传递给它。然后调用 is_valid()
方法进行数据验证,如果验证通过,则可以通过 serializer.validated_data
获取验证后的数据。
create()
和 update()
方法,可以方便地进行数据的创建和更新操作。以下是一个定义和使用模型序列化器的示例:
from rest_framework import serializers
from .models import User
class UserModelSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['name', 'age']
user = User.objects.get(id=1)
serializer = UserModelSerializer(user)
print(serializer.data)
在这个示例中,我们定义了一个 UserModelSerializer
类,通过 Meta
类指定了关联的模型类 User
和需要序列化的字段 ['name', 'age']
。然后创建了一个 UserModelSerializer
实例,并将一个 User
模型对象传递给它,最后获取序列化后的数据。
Meta
类的其他属性来指定一些额外的元数据,如 read_only_fields
、write_only_fields
等。字段级验证是对单个字段进行验证的方法。可以通过在序列化器类中定义以 validate_
命名的方法来实现。以下是一个示例:
from rest_framework import serializers
class UserSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
age = serializers.IntegerField()
def validate_age(self, value):
if value < 0:
raise serializers.ValidationError("年龄不能为负数")
return value
在这个示例中,我们定义了一个 validate_age
方法,用于验证 age
字段的值是否为负数。如果是负数,则抛出 ValidationError
异常。
对象级验证是对整个对象进行验证的方法。可以通过在序列化器类中定义 validate
方法来实现。以下是一个示例:
from rest_framework import serializers
class UserSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
age = serializers.IntegerField()
def validate(self, data):
if data.get('name') == 'Admin' and data.get('age') < 18:
raise serializers.ValidationError("管理员年龄必须大于等于 18 岁")
return data
在这个示例中,我们定义了一个 validate
方法,用于验证整个对象的数据。如果用户名是 Admin
且年龄小于 18 岁,则抛出 ValidationError
异常。
除了字段级验证和对象级验证,还可以定义自定义验证器,并将其应用到字段上。以下是一个示例:
from rest_framework import serializers
def validate_even(value):
if value % 2 != 0:
raise serializers.ValidationError("该字段必须为偶数")
return value
class NumberSerializer(serializers.Serializer):
number = serializers.IntegerField(validators=[validate_even])
在这个示例中,我们定义了一个 validate_even
验证器,用于验证字段的值是否为偶数。然后将该验证器应用到 NumberSerializer
类的 number
字段上。
在 Django REST framework(DRF)中,视图是处理客户端请求并返回响应的核心组件。视图可以根据不同的需求和场景,采用不同的实现方式,下面我们将详细介绍几种常见的视图类型。
基于函数的视图是最基本的视图形式,它就是一个普通的 Python 函数,接收一个请求对象作为参数,并返回一个响应对象。以下是一个简单的示例:
from django.http import JsonResponse
def simple_view(request):
data = {'message': 'Hello, World!'}
return JsonResponse(data)
在这个示例中,simple_view
函数接收一个 request
对象,然后创建一个包含消息的字典 data
,最后使用 JsonResponse
返回一个 JSON 格式的响应。
DRF 提供了一些装饰器来简化基于函数的视图的编写。例如,@api_view
装饰器可以用来指定视图支持的 HTTP 请求方法。
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['GET'])
def get_view(request):
data = {'message': 'This is a GET request.'}
return Response(data)
在这个示例中,@api_view(['GET'])
装饰器指定了该视图只支持 GET 请求。如果客户端发送其他类型的请求,DRF 会自动返回一个 405 Method Not Allowed 响应。
基于函数的视图可以通过判断 request.method
属性来处理不同的 HTTP 请求方法。
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['GET', 'POST'])
def mixed_view(request):
if request.method == 'GET':
data = {'message': 'This is a GET request.'}
elif request.method == 'POST':
data = {'message': 'This is a POST request.'}
return Response(data)
在这个示例中,mixed_view
视图支持 GET 和 POST 请求。根据请求的方法不同,返回不同的响应数据。
基于类的视图是将视图的逻辑封装在类中,通过类的方法来处理不同的 HTTP 请求方法。以下是一个简单的示例:
from django.http import JsonResponse
from django.views import View
class SimpleClassView(View):
def get(self, request):
data = {'message': 'This is a GET request from class view.'}
return JsonResponse(data)
在这个示例中,SimpleClassView
类继承自 View
类,并实现了 get
方法来处理 GET 请求。
DRF 提供了 APIView
类,它是基于类的视图的基类,提供了更多的功能和灵活性。
from rest_framework.views import APIView
from rest_framework.response import Response
class APIClassView(APIView):
def get(self, request):
data = {'message': 'This is a GET request from APIView.'}
return Response(data)
在这个示例中,APIClassView
类继承自 APIView
类,并实现了 get
方法。APIView
类会自动处理请求和响应的序列化和反序列化,以及权限验证等功能。
类视图有一些常用的方法和属性:
方法:
get
:处理 GET 请求。post
:处理 POST 请求。put
:处理 PUT 请求。patch
:处理 PATCH 请求。delete
:处理 DELETE 请求。属性:
request
:当前的请求对象。kwargs
:URL 中的关键字参数。通用视图是 DRF 提供的一组预定义的视图,它们封装了常见的视图逻辑,如列表视图、详情视图等。使用通用视图可以减少代码的重复,提高开发效率。
列表视图用于显示一组对象的列表。以下是一个简单的列表视图示例:
from rest_framework.generics import ListAPIView
from .models import MyModel
from .serializers import MyModelSerializer
class MyModelListView(ListAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
在这个示例中,MyModelListView
类继承自 ListAPIView
类,并指定了查询集和序列化器类。
详情视图用于显示单个对象的详细信息。以下是一个简单的详情视图示例:
from rest_framework.generics import RetrieveAPIView
from .models import MyModel
from .serializers import MyModelSerializer
class MyModelDetailView(RetrieveAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
在这个示例中,MyModelDetailView
类继承自 RetrieveAPIView
类,并指定了查询集和序列化器类。
通用视图是由多个混合类组合而成的。混合类是一些具有特定功能的类,可以通过继承和组合来创建自定义的视图。常见的混合类有:
ListModelMixin
:提供列表视图的功能。CreateModelMixin
:提供创建对象的功能。RetrieveModelMixin
:提供详情视图的功能。UpdateModelMixin
:提供更新对象的功能。DestroyModelMixin
:提供删除对象的功能。以下是一个使用混合类创建自定义视图的示例:
from rest_framework.mixins import ListModelMixin, CreateModelMixin
from rest_framework.generics import GenericAPIView
from .models import MyModel
from .serializers import MyModelSerializer
class MyCustomView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
在这个示例中,MyCustomView
类继承了 ListModelMixin
、CreateModelMixin
和 GenericAPIView
类,并实现了 get
和 post
方法来处理 GET 和 POST 请求。
视图集是一种将相关的视图逻辑组合在一起的方式。它将不同的 HTTP 请求方法映射到不同的操作上,如列表、详情、创建、更新、删除等。使用视图集可以进一步简化代码,提高开发效率。
以下是一个简单的视图集示例:
from rest_framework.viewsets import ModelViewSet
from .models import MyModel
from .serializers import MyModelSerializer
class MyModelViewSet(ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
在这个示例中,MyModelViewSet
类继承自 ModelViewSet
类,并指定了查询集和序列化器类。ModelViewSet
类提供了列表、详情、创建、更新、删除等操作的默认实现。
视图集需要与路由进行关联,才能将请求分发到相应的视图方法上。DRF 提供了 DefaultRouter
来自动生成路由。
from rest_framework.routers import DefaultRouter
from .views import MyModelViewSet
router = DefaultRouter()
router.register(r'mymodels', MyModelViewSet)
urlpatterns = router.urls
在这个示例中,使用 DefaultRouter
注册了 MyModelViewSet
视图集,并指定了路由前缀为 mymodels
。router.urls
会自动生成与视图集对应的 URL 模式。
通过以上介绍,我们详细了解了 DRF 中几种常见的视图类型,包括基于函数的视图、基于类的视图、通用视图和视图集。不同的视图类型适用于不同的场景,可以根据实际需求选择合适的视图类型来开发 RESTful API。
在 Web 开发中,路由就像是一位聪明的“交通指挥家”,它的主要作用是将客户端的请求(比如浏览器发出的请求)准确地引导到对应的视图函数或视图集上进行处理。
想象一下,一个 Web 应用就像是一座大型的商场,里面有各种各样的店铺(视图函数或视图集),而路由就是商场里的指示牌,告诉顾客(客户端请求)应该去哪个店铺(视图)。
具体来说,路由的作用包括:
http://example.com/products
时,路由会将这个请求导向处理产品列表的视图。/products/
映射到处理单个产品详情的视图。Django REST framework(DRF)提供了强大而灵活的路由机制,它可以帮助我们更高效地管理 API 的 URL 配置。
DRF 的路由机制主要基于 Django 的 URL 配置系统,并进行了扩展。它支持自动生成路由,减少了手动编写 URL 配置的工作量。
DRF 提供了两种主要的路由类:DefaultRouter
和 SimpleRouter
。这两个路由类可以根据视图集自动生成一系列的 URL 模式,例如列表视图、详情视图、创建视图等。
例如,对于一个 ProductViewSet
视图集,使用 DRF 的路由机制可以自动生成 /products/
(列表视图)和 /products/
(详情视图)等 URL 模式。
手动配置路由就像是自己一步一步地绘制商场的指示牌️,虽然麻烦一些,但可以让我们对 URL 配置有更精细的控制。
在 Django 中,我们可以使用 urlpatterns
列表来手动配置路由。例如:
from django.urls import path
from .views import ProductList, ProductDetail
urlpatterns = [
path('products/', ProductList.as_view(), name='product-list'),
path('products//' , ProductDetail.as_view(), name='product-detail'),
]
在这个例子中,我们手动将 /products/
映射到 ProductList
视图,将 /products/
映射到 ProductDetail
视图。
在实际开发中,我们可能会有不同类型的视图,如函数视图和类视图,需要根据不同的视图类型进行路由配置。
函数视图是最简单的视图类型,我们可以直接将函数名作为路由的处理函数。例如:
from django.urls import path
from .views import product_list, product_detail
urlpatterns = [
path('products/', product_list, name='product-list'),
path('products//' , product_detail, name='product-detail'),
]
类视图提供了更强大的功能和更好的代码组织,我们需要使用 as_view()
方法将类视图转换为可调用的视图函数。例如:
from django.urls import path
from .views import ProductListView, ProductDetailView
urlpatterns = [
path('products/', ProductListView.as_view(), name='product-list'),
path('products//' , ProductDetailView.as_view(), name='product-detail'),
]
DefaultRouter
是 DRF 提供的一个非常方便的路由类,它可以根据视图集自动生成一系列的 URL 模式,并且还会自动生成一个 API 根视图。
使用 DefaultRouter
的步骤如下:
DefaultRouter
类:from rest_framework.routers import DefaultRouter
DefaultRouter
实例:router = DefaultRouter()
from .views import ProductViewSet
router.register(r'products', ProductViewSet)
urlpatterns = router.urls
这样,DefaultRouter
会自动生成 /products/
(列表视图)、/products/
(详情视图)等 URL 模式,还会生成一个 API 根视图,方便我们查看 API 的整体结构。
SimpleRouter
与 DefaultRouter
类似,也可以根据视图集自动生成 URL 模式,但它不会生成 API 根视图。
使用 SimpleRouter
的步骤与 DefaultRouter
基本相同:
SimpleRouter
类:from rest_framework.routers import SimpleRouter
SimpleRouter
实例:router = SimpleRouter()
from .views import ProductViewSet
router.register(r'products', ProductViewSet)
urlpatterns = router.urls
有时候,自动生成的路由可能无法满足我们的需求,这时候就需要进行自定义路由。
我们可以继承 DefaultRouter
或 SimpleRouter
类,并重写一些方法来实现自定义路由。例如,我们可以自定义 URL 模式的生成规则。
from rest_framework.routers import DefaultRouter
class CustomRouter(DefaultRouter):
def get_urls(self):
urls = super().get_urls()
# 在这里可以添加自定义的 URL 模式
custom_urls = [
# 自定义 URL 模式
]
urls.extend(custom_urls)
return urls
router = CustomRouter()
router.register(r'products', ProductViewSet)
urlpatterns = router.urls
通过自定义路由,我们可以根据具体的业务需求灵活地调整 URL 配置。
认证(Authentication)是指系统对用户身份进行验证的过程,就像你进入一个高级俱乐部,门口的保安会检查你的会员卡来确认你是否有进入的资格。在软件开发中,认证就是要确定访问系统的用户到底是谁,确保只有合法的用户能够访问系统资源。
Django REST framework(DRF)提供了一些内置的认证类,方便开发者快速实现认证功能。
有时候,DRF 内置的认证类可能无法满足项目的特殊需求,这时候就需要自定义认证类。
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from myapp.models import MyUser
class CustomAuthentication(BaseAuthentication):
def authenticate(self, request):
# 从请求头中获取自定义的认证信息
auth_header = request.headers.get('X-Custom-Auth')
if not auth_header:
return None # 没有提供认证信息,返回 None
try:
# 验证认证信息,这里假设是用户 ID
user_id = int(auth_header)
user = MyUser.objects.get(id=user_id)
except (ValueError, MyUser.DoesNotExist):
raise AuthenticationFailed('Invalid authentication credentials.')
return (user, None) # 返回认证成功的用户和 None
权限(Permissions)是指系统对用户访问资源和执行操作的限制。即使一个用户通过了认证,也不意味着他可以随意访问系统的所有资源和执行所有操作。就像在一个公司里,不同职位的员工有不同的权限,普通员工只能访问自己的工作区域和相关文件,而经理可能有更高的权限可以访问更多的资源。
DRF 提供了一些内置的权限类,方便开发者实现权限控制。
同样,当 DRF 内置的权限类无法满足需求时,我们可以自定义权限类。
from rest_framework.permissions import BasePermission
class CustomPermission(BasePermission):
def has_permission(self, request, view):
# 假设只有用户名为 'special_user' 的用户才有访问权限
if request.user.username == 'special_user':
return True
return False
在 DRF 中,可以在视图类中单独配置认证和权限。
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
class MyView(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({'message': 'Hello, authenticated user!'})
在这个示例中,MyView 视图使用 TokenAuthentication 进行认证,只有经过认证的用户才能访问该视图,并且使用 IsAuthenticated 权限类确保只有认证用户才能执行该视图的操作。
除了在视图中单独配置,还可以在项目的 settings.py 文件中进行全局配置。
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
这样配置后,所有的视图都会默认使用 TokenAuthentication 进行认证,并且只有经过认证的用户才能访问。如果某个视图需要特殊的认证或权限配置,可以在视图类中单独覆盖默认配置。
通过以上的认证和权限配置,可以确保系统的安全性和数据的完整性,让不同的用户只能访问和操作他们有权限的资源和功能。
节流是一种在软件开发中常用的优化技术,它的主要作用就像是给水龙头安装了一个限流装置,让水流(请求)按照一定的速率流出,而不是一股脑地全部涌出来。
在实际的应用场景中,当用户频繁触发某个操作时,例如频繁点击按钮、快速滚动页面触发的事件等,如果不加以限制,可能会导致服务器压力过大,出现性能问题,甚至崩溃。节流通过限制某个函数在一定时间内的执行次数,避免了这种过度请求的情况,使得系统能够更加稳定、高效地运行。
比如,在一个电商网站的搜索框中,用户可能会快速输入关键词进行搜索。如果每输入一个字符就立即向服务器发送一次搜索请求,服务器会不堪重负。使用节流技术后,我们可以设置在用户输入停止一段时间后再发送请求,这样既保证了用户的搜索体验,又减轻了服务器的压力。
节流在很多场景中都有广泛的应用,以下是一些常见的例子:
按钮点击事件:在一些需要提交表单或者执行重要操作的按钮上,为了防止用户误操作或者恶意快速点击,我们可以使用节流。例如,在一个注册按钮上,使用节流后,用户点击按钮后,在一定时间内再次点击将不会触发注册请求,避免重复提交表单。
滚动加载:当我们浏览网页时,经常会遇到滚动页面加载更多内容的情况。如果不使用节流,用户快速滚动页面时,会触发大量的加载请求,导致页面卡顿。通过节流,我们可以限制在一定时间内只触发一次加载请求,提高页面的性能和用户体验。
窗口大小改变事件:当用户调整浏览器窗口大小时,会触发 resize
事件。如果在这个事件中执行一些复杂的计算或者重新布局的操作,频繁触发会导致性能问题。使用节流可以限制事件的触发频率,减少不必要的计算。
AnonRateThrottle
是 Django REST framework(DRF)中用于限制匿名用户请求速率的节流类。它就像是一个“门卫”,专门对没有登录的用户进行流量控制。
这个节流类会根据配置的速率限制匿名用户的请求次数。例如,我们可以配置为每分钟允许匿名用户发送 10 次请求。如果匿名用户在一分钟内发送的请求超过了这个数量,后续的请求将会被拒绝,服务器会返回一个 429 Too Many Requests 错误。
以下是一个简单的配置示例:
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/min', # 每分钟允许 10 次请求
}
}
UserRateThrottle
是用于限制已登录用户请求速率的节流类。与 AnonRateThrottle
不同,它针对的是已经通过身份验证的用户。
同样,我们可以根据需要配置已登录用户的请求速率。例如,我们可以设置为每小时允许每个用户发送 100 次请求。这样可以防止个别用户过度使用系统资源,保证系统的公平性和稳定性。
配置示例如下:
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.UserRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'user': '100/hour', # 每小时允许 100 次请求
}
}
ScopedRateThrottle
是一个更灵活的节流类,它允许我们根据不同的视图或者操作范围来设置不同的请求速率。就像是为不同的房间设置了不同的门禁规则。
例如,我们可以为某个特定的 API 视图设置一个较高的请求速率,而对其他视图设置较低的速率。这样可以根据不同的业务需求进行精细的流量控制。
以下是一个使用 ScopedRateThrottle
的示例:
from rest_framework.throttling import ScopedRateThrottle
from rest_framework.views import APIView
from rest_framework.response import Response
class MyView(APIView):
throttle_scope = 'my_scope' # 定义节流范围
def get(self, request):
return Response({'message': 'Hello, World!'})
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.ScopedRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'my_scope': '20/min', # 每分钟允许 20 次请求
}
}
有时候,DRF 提供的内置节流类可能无法满足我们的特定需求,这时候就需要自定义节流类。自定义节流类就像是我们自己打造一个个性化的“流量控制器”️。
要自定义节流类,我们需要继承 rest_framework.throttling.BaseThrottle
类,并实现 allow_request
方法。allow_request
方法用于判断当前请求是否允许通过,如果允许则返回 True
,否则返回 False
。
以下是一个简单的自定义节流类示例,该类限制每个用户在 5 秒内只能发送一次请求:
from rest_framework.throttling import BaseThrottle
import time
class CustomThrottle(BaseThrottle):
def __init__(self):
self.history = {}
def allow_request(self, request, view):
user = request.user
now = time.time()
if user in self.history:
last_request_time = self.history[user]
if now - last_request_time < 5: # 5 秒内只允许一次请求
return False
self.history[user] = now
return True
自定义好节流类后,我们需要在视图中应用它。在 DRF 中,我们可以通过在视图类中设置 throttle_classes
属性来指定使用的节流类。
以下是一个在视图中应用自定义节流类的示例:
from rest_framework.views import APIView
from rest_framework.response import Response
from .throttles import CustomThrottle # 导入自定义节流类
class MyCustomView(APIView):
throttle_classes = [CustomThrottle] # 应用自定义节流类
def get(self, request):
return Response({'message': 'This is a custom view with custom throttling.'})
这样,当用户访问 MyCustomView
时,就会受到自定义节流类的限制。
在数据处理和展示的过程中,当数据量非常大时,如果一次性将所有数据都展示给用户,会带来很多问题:
分页就是为了解决这些问题而出现的。它将大量的数据分成若干个小的“页面”,每次只加载和展示其中的一个页面,这样既减轻了服务器的负担,又提高了用户体验。
分页在很多场景中都有广泛的应用:
PageNumberPagination
是 DRF 中最常用的分页类之一,它基于页码来进行分页。用户可以通过指定页码来获取相应页面的数据。
page_size
(每页显示的数据数量)、page_query_param
(页码参数名)等属性来定制分页行为。from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
class CustomPageNumberPagination(PageNumberPagination):
page_size = 10 # 每页显示 10 条数据
page_size_query_param = 'page_size' # 允许用户通过参数指定每页显示的数据数量
max_page_size = 100 # 每页最大显示的数据数量
def get_paginated_response(self, data):
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
},
'count': self.page.paginator.count,
'results': data
})
LimitOffsetPagination
基于偏移量和限制数量来进行分页。limit
表示每页显示的数据数量,offset
表示从第几条数据开始显示。
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.response import Response
class CustomLimitOffsetPagination(LimitOffsetPagination):
default_limit = 10 # 默认每页显示 10 条数据
limit_query_param = 'limit' # 限制数量的参数名
offset_query_param = 'offset' # 偏移量的参数名
max_limit = 100 # 最大限制数量
def get_paginated_response(self, data):
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
},
'count': self.count,
'results': data
})
CursorPagination
是一种基于游标(cursor)的分页方式,它通过一个不透明的游标来定位数据,而不是使用页码或偏移量。
CursorPagination
可以提高性能,因为它不需要计算总页数。from rest_framework.pagination import CursorPagination
from rest_framework.response import Response
class CustomCursorPagination(CursorPagination):
page_size = 10 # 每页显示 10 条数据
ordering = '-created_at' # 按照创建时间降序排列
cursor_query_param = 'cursor' # 游标的参数名
def get_paginated_response(self, data):
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
},
'results': data
})
有时候,DRF 内置的分页类可能无法满足我们的需求,这时候就需要自定义分页类。自定义分页类需要继承自 rest_framework.pagination.BasePagination
类,并实现 paginate_queryset
和 get_paginated_response
方法。
from rest_framework.pagination import BasePagination
from rest_framework.response import Response
class CustomPagination(BasePagination):
page_size = 15 # 每页显示 15 条数据
def paginate_queryset(self, queryset, request, view=None):
page = int(request.query_params.get('page', 1))
start = (page - 1) * self.page_size
end = start + self.page_size
return list(queryset[start:end])
def get_paginated_response(self, data):
return Response({
'results': data
})
在视图中应用自定义分页类非常简单,只需要在视图类中指定 pagination_class
属性为自定义的分页类即可。
from rest_framework.viewsets import ModelViewSet
from .models import MyModel
from .serializers import MyModelSerializer
from .pagination import CustomPagination
class MyModelViewSet(ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
pagination_class = CustomPagination
这样,在访问 MyModelViewSet
对应的接口时,就会使用自定义的分页逻辑进行分页啦。
在处理数据时,过滤和排序是非常重要的操作,它们可以帮助我们更高效地获取和展示所需的数据。在 Django REST framework (DRF) 中,提供了强大的过滤和排序机制,下面我们来详细了解一下。
过滤机制允许我们根据特定的条件筛选出符合要求的数据,就像是从一堆物品中挑选出我们需要的部分。
过滤的主要作用是从大量的数据中筛选出我们需要的子集,提高数据的查询效率和精准度。例如,在一个电商网站中,我们可能只想查看价格在某个范围内的商品,或者只查看某个品牌的商品。通过过滤,我们可以快速地找到满足这些条件的商品,而不需要遍历整个商品列表。
DRF 提供了几种内置的过滤后端,方便我们快速实现过滤功能。
django-filter
库。我们可以通过定义过滤字段,让用户可以根据这些字段进行过滤。例如:from rest_framework import generics
from django_filters.rest_framework import DjangoFilterBackend
from .models import Product
from .serializers import ProductSerializer
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields = ['price', 'brand']
在这个例子中,用户可以通过在 URL 中添加 ?price=100&brand=Apple
这样的参数来过滤商品。
?search=keyword
来搜索包含该关键词的数据。例如:from rest_framework import generics
from rest_framework.filters import SearchFilter
from .models import Product
from .serializers import ProductSerializer
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [SearchFilter]
search_fields = ['name', 'description']
?ordering=field_name
来对数据进行排序。有时候,内置的过滤后端可能无法满足我们的需求,这时候就需要自定义过滤后端。自定义过滤后端需要继承 BaseFilterBackend
类,并实现 filter_queryset
方法。例如:
from rest_framework.filters import BaseFilterBackend
from .models import Product
class CustomFilterBackend(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
# 自定义过滤逻辑
min_price = request.query_params.get('min_price')
if min_price is not None:
queryset = queryset.filter(price__gte=min_price)
return queryset
然后在视图中使用自定义过滤后端:
from rest_framework import generics
from .models import Product
from .serializers import ProductSerializer
from .filters import CustomFilterBackend
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [CustomFilterBackend]
排序机制允许我们按照特定的规则对数据进行排序,就像是给物品按照大小、颜色等规则进行排列一样。
排序的主要作用是让数据按照我们期望的顺序展示,方便用户查看和比较。例如,在一个商品列表中,我们可以按照价格从低到高或者从高到低进行排序,让用户可以快速找到价格合适的商品。
在 DRF 中,我们可以使用 OrderingFilter
来实现排序功能。首先,在视图中添加 OrderingFilter
到 filter_backends
中,并指定可排序的字段。例如:
from rest_framework import generics
from rest_framework.filters import OrderingFilter
from .models import Product
from .serializers import ProductSerializer
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [OrderingFilter]
ordering_fields = ['price', 'created_at']
ordering = ['-created_at'] # 默认按照创建时间降序排列
用户可以通过在 URL 中添加 ?ordering=price
来按照价格升序排列,或者添加 ?ordering=-price
来按照价格降序排列。
如果内置的排序功能无法满足我们的需求,我们也可以自定义排序逻辑。和自定义过滤后端类似,我们可以在视图中重写 get_queryset
方法来实现自定义排序。例如:
from rest_framework import generics
from .models import Product
from .serializers import ProductSerializer
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
def get_queryset(self):
queryset = super().get_queryset()
# 自定义排序逻辑
sort_by = self.request.query_params.get('sort_by')
if sort_by == 'custom':
# 自定义排序规则
queryset = sorted(queryset, key=lambda x: x.custom_score)
return queryset
在这个例子中,用户可以通过在 URL 中添加 ?sort_by=custom
来使用自定义的排序规则。
通过过滤和排序机制,我们可以让数据的查询和展示更加灵活和高效,为用户提供更好的体验。
在软件开发的过程中,版本控制就像是一位“时间管理员”⏰,它有着至关重要的作用:
版本控制在很多场景下都有着广泛的应用:
URLPathVersioning
是 DRF(Django REST Framework)中一种基于 URL 路径的版本控制方案。在这种方案中,版本信息会直接包含在 URL 的路径中。
例如,我们可以定义如下的 URL 格式:
# urls.py
from django.urls import path
from rest_framework.routers import DefaultRouter
from myapp.views import MyViewSet
router = DefaultRouter()
router.register(r'v1/myresource', MyViewSet, basename='myresource')
router.register(r'v2/myresource', MyViewSet, basename='myresource')
urlpatterns = [
path('', include(router.urls)),
]
在这个例子中,v1
和 v2
就是版本信息。当客户端请求 http://example.com/v1/myresource/
时,会使用版本 1 的接口;当请求 http://example.com/v2/myresource/
时,会使用版本 2 的接口。
这种方案的优点是简单直观,版本信息一目了然,开发人员和客户端都很容易理解。缺点是会使 URL 变得冗长,并且如果版本更新频繁,需要不断修改 URL 配置。
QueryParameterVersioning
是通过 URL 的查询参数来指定版本的。客户端在请求时,通过在 URL 中添加版本参数来指定使用的版本。
例如,客户端可以这样请求:
http://example.com/myresource/?version=v1
在 DRF 中,我们可以这样配置:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning',
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': ['v1', 'v2'],
'VERSION_PARAM': 'version'
}
在这个配置中,VERSION_PARAM
指定了查询参数的名称,DEFAULT_VERSION
指定了默认版本,ALLOWED_VERSIONS
指定了允许的版本列表。
这种方案的优点是灵活性高,不需要修改 URL 的路径,只需要在查询参数中指定版本即可。缺点是不够直观,客户端需要在每次请求时都带上版本参数。
AcceptHeaderVersioning
是通过 HTTP 请求头中的 Accept
字段来指定版本的。客户端在请求时,通过在 Accept
字段中添加版本信息来指定使用的版本。
例如,客户端可以这样发送请求:
Accept: application/json; version=v1
在 DRF 中,我们可以这样配置:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning',
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': ['v1', 'v2'],
'VERSION_PARAM': 'version'
}
这种方案的优点是不会影响 URL 的结构,使 URL 更加简洁。缺点是对客户端的要求较高,客户端需要正确设置 Accept
头。
有时候,DRF 内置的版本控制方案可能无法满足我们的需求,这时候就需要自定义版本控制逻辑。
下面是一个简单的自定义版本控制类的示例:
from rest_framework.versioning import BaseVersioning
from rest_framework.exceptions import APIException
class CustomVersioning(BaseVersioning):
def determine_version(self, request, *args, **kwargs):
# 从请求头中获取版本信息
version = request.headers.get('X-Custom-Version')
if not version:
# 如果没有提供版本信息,抛出异常
raise APIException('Version information is missing in the request headers.')
if version not in ['v1', 'v2']:
# 如果版本信息不在允许的列表中,抛出异常
raise APIException('Invalid version number.')
return version
在这个示例中,我们自定义了一个版本控制类 CustomVersioning
,它从请求头的 X-Custom-Version
字段中获取版本信息,并进行合法性检查。
要在项目中应用自定义版本控制,我们需要在 settings.py
中进行配置:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'myapp.versioning.CustomVersioning',
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': ['v1', 'v2'],
'VERSION_PARAM': 'version'
}
同时,在视图中也可以指定使用的版本控制类:
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from myapp.versioning import CustomVersioning
class MyView(APIView):
versioning_class = CustomVersioning
def get(self, request, *args, **kwargs):
version = request.version
return Response({'version': version})
通过这样的配置,我们就可以在项目中使用自定义的版本控制方案了。
在软件开发的世界里,测试就像是一位严谨的“质量检查员”,它对于使用 Django REST Framework(DRF)构建的项目来说至关重要。
DRF 作为一个强大的 Django 扩展,其测试具有一些独特的特点:
TestCase
、APIClient
等,使得我们可以方便地编写和运行测试用例。APIClient
可以模拟 GET、POST、PUT、DELETE 等请求,验证 API 的功能和性能。视图是 DRF 中处理 HTTP 请求的核心组件,测试视图可以确保其功能的正确性。以下是编写视图测试用例的一般步骤:
from django.test import TestCase, APIClient
from django.urls import reverse
from your_app.models import YourModel # 假设你的视图与某个模型相关
class YourViewTestCase(TestCase):
def setUp(self):
# 在每个测试方法执行前进行一些初始化操作,例如创建测试数据
self.client = APIClient()
self.your_model = YourModel.objects.create(name='Test Object')
self.url = reverse('your-view-name') # 根据视图的 URL 名称获取 URL
def test_get_view(self):
# 测试 GET 请求
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200) # 检查响应状态码是否为 200
# 可以进一步检查响应数据的内容
self.assertEqual(len(response.data), 1)
def test_post_view(self):
# 测试 POST 请求
data = {'name': 'New Object'}
response = self.client.post(self.url, data, format='json')
self.assertEqual(response.status_code, 201) # 检查响应状态码是否为 201(创建成功)
# 可以检查数据库中是否新增了记录
self.assertEqual(YourModel.objects.count(), 2)
序列化器用于将模型实例转换为 JSON 数据,以及将 JSON 数据反序列化为模型实例。测试序列化器可以确保数据的正确转换。
from django.test import TestCase
from your_app.serializers import YourSerializer
from your_app.models import YourModel
class YourSerializerTestCase(TestCase):
def setUp(self):
self.your_model = YourModel.objects.create(name='Test Object')
def test_serializer(self):
# 测试序列化功能
serializer = YourSerializer(self.your_model)
data = serializer.data
self.assertEqual(data['name'], 'Test Object')
def test_deserializer(self):
# 测试反序列化功能
data = {'name': 'New Object'}
serializer = YourSerializer(data=data)
self.assertTrue(serializer.is_valid()) # 检查数据是否有效
new_object = serializer.save()
self.assertEqual(new_object.name, 'New Object')
在 DRF 中,认证和权限是保护 API 资源的重要机制。测试认证和权限可以确保只有授权的用户才能访问受保护的资源。
from django.test import TestCase, APIClient
from django.urls import reverse
from rest_framework.authtoken.models import Token
from your_app.models import YourModel
from your_app.views import YourProtectedView
class AuthenticationAndPermissionTestCase(TestCase):
def setUp(self):
self.client = APIClient()
self.your_model = YourModel.objects.create(name='Test Object')
self.url = reverse('your-protected-view-name')
# 创建一个用户并获取其令牌
self.user = User.objects.create_user(username='testuser', password='testpass')
self.token = Token.objects.create(user=self.user)
def test_unauthenticated_access(self):
# 测试未认证用户的访问
response = self.client.get(self.url)
self.assertEqual(response.status_code, 401) # 检查响应状态码是否为 401(未认证)
def test_authenticated_access(self):
# 测试认证用户的访问
self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200) # 检查响应状态码是否为 200
Django 提供了一个内置的测试运行器,可以方便地运行我们编写的测试用例。在项目的根目录下,使用以下命令来运行测试:
python manage.py test
这个命令会自动发现项目中所有以 test
开头的测试文件和测试类,并执行其中的测试方法。运行测试时,Django 会创建一个测试数据库,确保测试不会影响到生产数据库。
如果只想运行某个特定的测试模块或测试类,可以指定其路径:
python manage.py test your_app.tests.YourTestCase
测试覆盖率是衡量测试用例对代码的覆盖程度的指标。通过分析测试覆盖率,我们可以了解哪些代码还没有被测试到,从而有针对性地编写更多的测试用例。
要分析测试覆盖率,我们可以使用 coverage.py
工具。首先,安装 coverage.py
:
pip install coverage
然后,使用以下命令来运行测试并生成覆盖率报告:
coverage run --source='.' manage.py test
--source='.'
表示要分析整个项目的代码覆盖率。运行完测试后,使用以下命令生成 HTML 格式的覆盖率报告:
coverage html
这会在项目根目录下生成一个 htmlcov
文件夹,打开其中的 index.html
文件,就可以在浏览器中查看详细的覆盖率报告。报告中会显示哪些代码行被测试到了,哪些还没有被覆盖,帮助我们找出测试的不足之处。
通过以上步骤,我们可以全面地对 DRF 项目进行测试和覆盖率分析,确保项目的质量和稳定性。
在应用程序中,数据库查询往往是性能瓶颈之一。以下是一些常见的数据库查询优化方法:
-- 在 MySQL 中为用户表的邮箱字段创建索引
CREATE INDEX idx_user_email ON users (email);
SELECT *
,而是明确指定需要查询的字段。例如,只需要查询用户的姓名和邮箱时:# Django 示例
users = User.objects.values('name', 'email')
这样可以减少数据库传输的数据量,提高查询性能。
users = [User(name='user1', email='[email protected]'), User(name='user2', email='[email protected]')]
User.objects.bulk_create(users)
序列化器在将数据对象转换为可传输的格式(如 JSON)时,也可能会影响性能。以下是一些序列化器性能优化的方法:
fields
属性指定需要序列化的字段,避免序列化不必要的字段。from rest_framework import serializers
from .models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('name', 'email')
from django.core.cache import cache
from .serializers import UserSerializer
from .models import User
def get_user_serialized_data(user_id):
cached_data = cache.get(f'user_{user_id}_serialized')
if cached_data:
return cached_data
user = User.objects.get(id=user_id)
serializer = UserSerializer(user)
serialized_data = serializer.data
cache.set(f'user_{user_id}_serialized', serialized_data, 60 * 60) # 缓存 1 小时
return serialized_data
SerializerMethodField
来手动处理嵌套数据。视图是处理请求和返回响应的关键部分,以下是一些视图性能优化的方法:
from django.views.decorators.cache import cache_page
@cache_page(60 * 15) # 缓存 15 分钟
def my_view(request):
# 视图逻辑
return HttpResponse('Hello, World!')
import asyncio
from django.http import HttpResponse
async def async_view(request):
await asyncio.sleep(1) # 模拟异步操作
return HttpResponse('Async View')
PageNumberPagination
或 LimitOffsetPagination
。from rest_framework.pagination import PageNumberPagination
from rest_framework.viewsets import ModelViewSet
from .models import User
from .serializers import UserSerializer
class CustomPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100
class UserViewSet(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
pagination_class = CustomPagination
throttling
模块。渲染器用于将序列化后的数据转换为特定的格式,如 JSON、XML 等。以下是自定义渲染器的步骤:
from rest_framework.renderers import BaseRenderer
class CustomRenderer(BaseRenderer):
media_type = 'text/plain'
format = 'txt'
def render(self, data, accepted_media_type=None, renderer_context=None):
if isinstance(data, str):
return data.encode()
return str(data).encode()
from rest_framework.views import APIView
from rest_framework.response import Response
from .renderers import CustomRenderer
class CustomView(APIView):
renderer_classes = [CustomRenderer]
def get(self, request):
data = 'This is a custom rendered response.'
return Response(data)
解析器用于将请求中的数据解析为 Python 对象。以下是自定义解析器的步骤:
from rest_framework.parsers import BaseParser
class CustomParser(BaseParser):
media_type = 'text/plain'
def parse(self, stream, media_type=None, parser_context=None):
data = stream.read().decode()
return data
from rest_framework.views import APIView
from rest_framework.response import Response
from .parsers import CustomParser
class CustomParserView(APIView):
parser_classes = [CustomParser]
def post(self, request):
data = request.data
return Response({'received': data})
DRF 可以与许多第三方库集成,以扩展其功能。以下是一些常见的集成示例:
pip install django-filter
settings.py
中添加 'django_filters'
到 INSTALLED_APPS
。DjangoFilterBackend
进行过滤。from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from .models import User
from .serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields = ['name', 'email']
pip install django-rest-swagger
urls.py
中添加 Swagger 的路由。from rest_framework_swagger.views import get_swagger_view
schema_view = get_swagger_view(title='API Documentation')
urlpatterns = [
path('swagger/', schema_view),
# 其他路由
]
这样就可以通过访问 /swagger/
查看 API 文档。
通过以上的性能优化和功能扩展方法,可以让你的 DRF 应用更加高效和强大。
在开启一个项目之前,明确其功能是至关重要的,就像是建造一座房子,得先有清晰的设计蓝图。以下是确定项目功能的具体步骤:
数据库模型就像是项目的数据仓库,合理的设计能够提高数据的存储效率和查询性能。以下是设计数据库模型的一般步骤:
搭建项目框架就像是为项目搭建一个骨架,为后续的开发工作提供基础和结构️。以下是搭建项目框架的一般步骤:
django-admin startproject
命令创建项目。from rest_framework import serializers
from .models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'email']
from django.http import JsonResponse
from .models import User
from .serializers import UserSerializer
def user_list(request):
users = User.objects.all()
serializer = UserSerializer(users, many=True)
return JsonResponse(serializer.data, safe=False)
urls.py
文件中定义路由:from django.urls import path
from .views import user_list
urlpatterns = [
path('users/', user_list, name='user_list'),
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
]
}
from rest_framework.permissions import BasePermission
class IsAdminUser(BasePermission):
def has_permission(self, request, view):
return request.user.is_superuser
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '1000/day'
}
}
编写测试用例是确保项目质量的重要环节,它可以帮助我们发现代码中的缺陷和问题。以下是编写测试用例并进行测试的一般步骤:
将项目部署到生产环境是项目上线的最后一步,它需要确保项目在生产环境中稳定运行。以下是部署项目到生产环境的一般步骤: