Rest_framework介绍
序列化器Serializers
功能:序列化器用于将复杂的数据类型如Django模型实例或查询集转换为Python数据类型,通常是为了最终转换成JSON、XML等格式。同时,序列化器也提供数据验证功能,确保接收的数据符合预期的格式。
使用情况:当你需要从Django模型中获取数据并将其发送给客户端,或者接收客户端发送的数据并将其保存到Django模型中时,你需要使用序列化器
获取用户数据可以用序列化器进行验证得到有效数据在通过模型保存
from rest_framework import serializers
from .models import MyModel
class MySerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ['field1', 'field2', 'field3']
# 在视图中
from rest_framework.views import APIView
from rest_framework.response import Response
class MyView(APIView):
def post(self, request, *args, **kwargs):
serializer = MySerializer(data=request.data)
if serializer.is_valid():
# 处理验证后的数据
validated_data = serializer.validated_data
# 例如,创建新的数据库记录
instance = MyModel.objects.create(**validated_data)
return Response({"message": "数据已成功创建", "data": serializer.data})
else:
# 返回错误信息
return Response(serializer.errors, status=400)
将从数据库中得到的数据库进行json化
from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework.views import APIView
from rest_framework.response import Response
# 定义序列化器类
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'email'] # 指定要序列化的字段
# 定义视图类
class UserListView(APIView):
def get(self, request, *args, **kwargs):
# 从数据库中获取用户
users = User.objects.all()
# 实例化序列化器
serializer = UserSerializer(users, many=True)
# 返回序列化后的数据
return Response(serializer.data)
序列化钩子
使用 自定义字段:get_field_name(),自定义字段,bind,to_response()
自定义钩子(序列化)(重写to_response()方法)
自定义验证钩子(valite_value)
外键嵌套和只读字段设置(序列化器不会从data中读取该字段)
from rest_framework import serializers
from .models import User, Profile
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'email']
class ProfileSerializer(serializers.ModelSerializer):
user = UserSerializer() # 使用UserSerializer来序列化外键字段
class Meta:
model = Profile
fields = ['id', 'user', 'bio']
depth = 1 # 指定嵌套的深度,这里设置为1,表示会序列化外键关联对象的一层信息
class MySerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ['id', 'name', 'email', 'password']
read_only_fields = ['id']
视图views
APIView
- 这是DRF中最基本的视图类,它继承自Django的
View
类,但添加了一些额外的功能,如请求解析、渲染、异常处理等。 - 使用
APIView
时,你通常需要手动处理HTTP方法(如GET、POST等)。
GenericAPIView
- 这是一个更高级的视图类,它继承自
APIView
,并添加了一些通用的功能,如对象查找和序列化。 GenericAPIView
通常与mixin类一起使用,以提供特定的HTTP方法处理(如ListModelMixin
用于处理GET请求以列出对象)。
ViewSet
- ViewSets允许你将多个逻辑视图组合到一个类中。例如,你可以有一个
UserViewSet
类,该类同时处理用户对象的创建、检索、更新和删除(CRUD操作)。 - DRF提供了多种ViewSet类,如
ModelViewSet
和ReadOnlyModelViewSet
,它们基于GenericAPIView
并添加了一些额外的功能。
权限(Permissions)
功能:权限是确定已认证用户是否有权执行某个操作的过程。DRF提供了多种内置的权限类,并支持自定义权限。
使用情况:当你的API需要对用户访问进行权限控制时,你需要使用权限。
自定义认证类
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
class MyCustomAuthentication(BaseAuthentication):
def authenticate(self, request):
# 在这里实现你的自定义认证逻辑
# 如果验证成功,返回一个元组 (user, token)
# 如果验证失败,抛出 AuthenticationFailed 异常
# 示例逻辑(需要根据你的具体需求进行修改):
token = request.headers.get('Authorization')
if not token:
raise exceptions.AuthenticationFailed('No authentication token provided')
# 这里假设你有一个方法 `validate_token` 来验证 token 并返回 user
user = self.validate_token(token)
if not user:
raise exceptions.AuthenticationFailed('Invalid token')
return (user, token)
def validate_token(self, token):
# 这里应该实现 token 的验证逻辑,并返回相应的 user 对象
# 这只是一个示例,你应该根据你的需求来实现这个方法
return None # 在这里应该返回一个 user 对象或者 None
from rest_framework.views import APIView
from rest_framework.response import Response
from .authentication import MyCustomAuthentication
class MyView(APIView):
authentication_classes = [MyCustomAuthentication]
def get(self, request, format=None):
# 在这里实现你的视图逻辑
return Response({"message": "Hello, World!"})
# 全局注册 会在所有请求方法前调用
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'path.to.your.authentication.MyCustomAuthentication',
),
}
节流 Throttling
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.throttling import BaseThrottle, AnonRateThrottle
class MyCustomThrottle(BaseThrottle):
"""
自定义节流类,限制每分钟只能访问3次。
"""
RATE_LIMIT = '3/min'
def parse_rate(self, rate):
"""
给定一个速率字符串,返回一个元组,包含请求数和时间窗口(以秒为单位)。
"""
if rate is None:
return (None, None)
num, period = rate.split('/')
num_requests = int(num)
duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]
return (num_requests, duration)
def __init__(self):
self.rate, self.duration = self.parse_rate(self.RATE_LIMIT)
self.history = []
def allow_request(self, request, view):
"""
实现节流逻辑。
"""
self.now = self.now_in_seconds()
while self.history and self.history[-1] <= self.now - self.duration:
self.history.pop()
if len(self.history) < self.rate:
self.history.append(self.now)
return True
return False
def wait(self):
"""
返回需要等待的时间(秒)。
"""
return self.duration - (self.now - self.history[-1])
def now_in_seconds(self):
"""
返回当前时间的Unix时间戳(秒)。
你可以根据需要重写此方法,以便使用其他时间源或时间格式。
"""
return int(time.time())
from rest_framework.views import APIView
from rest_framework.response import Response
from .throttling import MyCustomThrottle # 假设自定义节流类在同目录下的throttling.py文件中
class MyView(APIView):
throttle_classes = [MyCustomThrottle] # 指定使用自定义节流类
def get(self, request, format=None):
return Response({"message": "Hello, world!"})
# settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '1000/day'
}
}
过滤器
功能:过滤是允许API消费者对返回的数据集进行筛选的机制。DRF支持多种过滤后端,如基于查询参数的过滤。
使用情况:当你的API需要支持对数据集的筛选功能时,你需要使用过滤。
from rest_framework import filters
class CustomFilterBackend(filters.BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
# 从request对象中提取查询参数
param = request.query_params.get('custom_param', None)
if param:
# 应用自定义过滤逻辑
queryset = queryset.filter(some_field=param)
return queryset
# 然后在你的视图中应用这个过滤器后端
class SomeView(generics.ListAPIView):
...
filter_backends = [CustomFilterBackend]
...
# API endpoint `/some-view/?custom_param=value` 将会调用CustomFilterBackend中的过滤逻辑。
- SearchFilter:
- 这个过滤器类支持简单的搜索功能,允许你使用一个名为
search
的查询参数来执行模糊匹配。 - 你可以通过
search_fields
属性来指定需要进行搜索的字段。
- 这个过滤器类支持简单的搜索功能,允许你使用一个名为
- OrderingFilter:
- 允许你通过查询参数对返回的查询集进行排序。
- 你可以使用
ordering_fields
属性来指定允许排序的字段。
- DjangoFilterBackend:
- 这是一个更高级的过滤器,它依赖于
django-filter
库,允许你根据多个字段和复杂的查询条件来过滤查询集。 - 你需要定义一个
FilterSet
类来指定过滤规则和字段,然后在视图中通过filterset_fields
或filter_class
属性来使用它。
- 这是一个更高级的过滤器,它依赖于
分页
- PageNumberPagination:
- 这是一个基于页码的分页类。客户端通过传递
page
查询参数来请求特定页的数据,并可以通过page_size
查询参数来设置每页的项目数。 - 你可以通过设置
PAGE_SIZE
属性来自定义默认的每页项目数,并通过MAX_PAGE_SIZE
属性来限制客户端可以请求的最大每页项目数。
- 这是一个基于页码的分页类。客户端通过传递
- LimitOffsetPagination:
- 这是一个基于限制和偏移量的分页类。客户端通过传递
limit
和offset
查询参数来指定返回的数据量和开始位置。 - 你可以通过设置
DEFAULT_LIMIT
属性来自定义默认的每页项目数,并通过MAX_LIMIT
属性来限制客户端可以请求的最大每页项目数。
- 这是一个基于限制和偏移量的分页类。客户端通过传递
- CursorPagination:
- 这是一个基于游标(Cursor-based)的分页类,适用于大型数据集,因为它允许对结果进行高效、一致的检索,而不需要知道数据集的总大小。
- 客户端通过传递
cursor
查询参数来请求下一页或上一页的数据。
from rest_framework.pagination import PageNumberPagination
class MyCustomPagination(PageNumberPagination):
page_size = 10 # 默认每页的项目数
page_size_query_param = 'size' # 允许客户端通过`size`查询参数来设置每页的项目数
max_page_size = 100 # 客户端可以请求的最大每页项目数
def get_paginated_response(self, data):
return Response({
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'count': self.page.paginator.count,
'results': data
})
from rest_framework import generics
from .models import MyModel
from .serializers import MyModelSerializer
from .pagination import MyCustomPagination
class MyListView(generics.ListAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
pagination_class = MyCustomPagination