Django开发设备管理系统(前后端分离)

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类,如ModelViewSetReadOnlyModelViewSet,它们基于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中的过滤逻辑。
  1. SearchFilter
    • 这个过滤器类支持简单的搜索功能,允许你使用一个名为search的查询参数来执行模糊匹配。
    • 你可以通过search_fields属性来指定需要进行搜索的字段。
  2. OrderingFilter
    • 允许你通过查询参数对返回的查询集进行排序。
    • 你可以使用ordering_fields属性来指定允许排序的字段。
  3. DjangoFilterBackend
    • 这是一个更高级的过滤器,它依赖于django-filter库,允许你根据多个字段和复杂的查询条件来过滤查询集。
    • 你需要定义一个FilterSet类来指定过滤规则和字段,然后在视图中通过filterset_fieldsfilter_class属性来使用它。

分页

  1. PageNumberPagination
    • 这是一个基于页码的分页类。客户端通过传递page查询参数来请求特定页的数据,并可以通过page_size查询参数来设置每页的项目数。
    • 你可以通过设置PAGE_SIZE属性来自定义默认的每页项目数,并通过MAX_PAGE_SIZE属性来限制客户端可以请求的最大每页项目数。
  2. LimitOffsetPagination
    • 这是一个基于限制和偏移量的分页类。客户端通过传递limitoffset查询参数来指定返回的数据量和开始位置。
    • 你可以通过设置DEFAULT_LIMIT属性来自定义默认的每页项目数,并通过MAX_LIMIT属性来限制客户端可以请求的最大每页项目数。
  3. 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
  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值