django rest_framework 笔记

180 阅读7分钟

0. rest_framework 介绍

为什么需要rest_framework?前后端分离的项目,需要将各个接口的数据以json或者xml的方式返回给前端调用,将object的数据进行转换就需要rest_framework这个框架了

1. 创建测试的 Django 项目

首先,确保已经安装了 Django 和 Django REST framework。如果尚未安装,可以通过以下命令安装:

pip install django djangorestframework

接下来,创建一个新的 Django 项目和应用:

django-admin startproject myproject
cd myproject
python manage.py startapp myapp

myapprest_framework 添加到 myproject/settings.py 文件中的 INSTALLED_APPS

INSTALLED_APPS = [
    ...
    'rest_framework',
    'myapp',
]

2. APIView

APIView 是 Django REST framework 提供的一个基础类,用于创建处理 HTTP 请求的视图。它提供了基本的请求处理功能,可以用来构建自定义的 API 视图。

以下是一个简单的 APIView 示例:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class ExampleAPIView(APIView):
    def get(self, request):
        data = {"message": "Hello, world!"}
        return Response(data, status=status.HTTP_200_OK)

myapp/urls.py 中配置 URL:

from django.urls import path
from .views import ExampleAPIView

urlpatterns = [
    path('example/', ExampleAPIView.as_view(), name='example'),
]

3. DefaultRouter

DefaultRouter 的作用

DefaultRouter 是 Django REST framework 提供的一个工具,用于自动生成 URL 路由。它特别适用于基于 ViewSet 的 API,可以自动为常见的 CRUD 操作生成 URL 路由。

1. 自动生成 URL 路由

DefaultRouter 可以根据 ViewSet 的方法自动为常见的 CRUD 操作生成 URL 路由。例如,一个 ModelViewSet 会自动为以下操作生成路由:

  • list(GET 请求,获取所有对象)
  • create(POST 请求,创建新对象)
  • retrieve(GET 请求,获取单个对象)
  • update(PUT 请求,更新单个对象)
  • partial_update(PATCH 请求,部分更新单个对象)
  • destroy(DELETE 请求,删除单个对象)

2. 简化 URL 配置

使用 DefaultRouter 可以减少手动编写 URL 配置的工作量,使代码更加简洁。你只需要注册 ViewSetDefaultRouter 会自动处理 URL 的生成和分发。

3. 支持多种 HTTP 方法

DefaultRouter 可以处理多种 HTTP 方法(如 GET、POST、PUT、DELETE 等),并自动映射到相应的视图方法。

示例:结合 DefaultRouter 和 path

假设你已经有一个 Django 项目和一个应用(例如 myapp),我们将在 myapp 中创建一个简单的 API,并结合使用 DefaultRouterpath

1. 定义模型

myapp/models.py 文件中定义一个简单的模型:

from django.db import models

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    completed = models.BooleanField(default=False)

    def __str__(self):
        return self.title

2. 创建序列化器

myapp/serializers.py 文件中定义一个序列化器:

from rest_framework import serializers
from .models import Task

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = '__all__'

3. 创建视图

myapp/views.py 文件中创建一个 ViewSet,用于处理任务的 CRUD 操作:

from rest_framework import viewsets
from .models import Task
from .serializers import TaskSerializer

class TaskViewSet(viewsets.ModelViewSet):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

4. 配置 URL

myapp/urls.py 文件中,结合使用 DefaultRouterpath

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views

# 创建一个路由器实例
router = DefaultRouter()

# 注册视图集
router.register(r'tasks', views.TaskViewSet, basename='task')

# 定义 urlpatterns
urlpatterns = [
    path('', views.home, name='home'),
    path('students/', views.StudentListAPIView.as_view(), name='student-list'),
    path('students/<int:pk>/', views.StudentDetailAPIView.as_view(), name='student-detail'),
    path('api/', include(router.urls)),  # 包含路由器生成的 URL
]

5. 运行数据库迁移

运行数据库迁移,以创建初始的数据库表:

python manage.py makemigrations
python manage.py migrate

6. 启动开发服务器

启动 Django 开发服务器:

python manage.py runserver

7. 测试 API

现在,你可以通过以下方式测试 API:

  • 获取所有任务

    curl -X GET http://127.0.0.1:8000/api/tasks/
    
  • 创建新任务

    curl -X POST -H "Content-Type: application/json" -d '{"title":"Task 1","description":"This is the first task","completed":false}' http://127.0.0.1:8000/api/tasks/
    
  • 获取单个任务

    curl -X GET http://127.0.0.1:8000/api/tasks/1/
    
  • 更新任务

    curl -X PUT -H "Content-Type: application/json" -d '{"title":"Task 1 Updated","description":"This is the updated first task","completed":true}' http://127.0.0.1:8000/api/tasks/1/
    
  • 删除任务

    curl -X DELETE http://127.0.0.1:8000/api/tasks/1/
    

4. 序列化器

在前后端分离开发中,对于 RESTful API 设置,我们一般需要将查询/更新数据以 JSON 方式返回,而 Django 本身所带的 ORM,仅仅支持数据的查询,并不能将查询得到的数据转换为 JSON/Python 的字典易读格式。Django REST framework 为我们提供了方便的序列化器自定义类,可以通过定义序列化类,方便地返回我们所需要的数据。

1.1 序列化器可以做什么?

  • 序列化

    • ORM 查询结果/对象 ---> 转换为 Python 原生数据类型/其他可读类型(如字典或列表)---> 便于转换为 JSON/其他传输格式
  • 反序列化

    • 请求数据(通常为 JSON)-> Python 可读取数据结构,对象/字典

简单来讲,其实就是实现了序列化与反序列化的过程,并且支持了数据验证。

1.2 序列化器的使用

定义序列化器

myapp/serializers.py 文件中定义一个序列化器:

from rest_framework import serializers
from .models import Task

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = '__all__'

使用序列化器

在视图中使用序列化器来处理数据:

from rest_framework import viewsets
from .models import Task
from .serializers import TaskSerializer

class TaskViewSet(viewsets.ModelViewSet):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

1.3 数据验证

序列化器不仅支持序列化和反序列化,还支持数据验证。你可以在序列化器中定义验证规则,确保接收到的数据符合预期。

from rest_framework import serializers
from .models import Task

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = '__all__'

    def validate_title(self, value):
        if len(value) < 3:
            raise serializers.ValidationError("标题至少需要3个字符")
        return value

总结

DefaultRouterpath 都是 Django REST framework 提供的工具,用于定义 URL 路由。DefaultRouter 适用于基于 ViewSet 的 API,可以自动为常见的 CRUD 操作生成 URL 路由,减少手动编写 URL 配置的工作量。path 提供了高度的灵活性,适用于需要自定义路由的场景。通过合理结合使用 DefaultRouterpath,你可以构建简洁、高效且易于维护的 RESTful API。

序列化器是 Django REST framework 的核心组件之一,它不仅支持将 ORM 查询结果转换为 JSON 格式,

Django REST Framework(DRF)中的 filter 主要用于对 API 返回的数据进行筛选。它让前端可以通过 URL 查询参数动态过滤结果集,提升接口灵活性和用户体验。


5. 过滤器

1. 基本原理

DRF 的过滤功能基于 Django 的 QuerySet filter 方法。常见的过滤方式有:

  • 内置过滤SearchFilterOrderingFilter
  • 第三方扩展django-filter(推荐)

2. 内置过滤器

SearchFilter

允许通过关键字搜索字段:

from rest_framework import filters

class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [filters.SearchFilter]
    search_fields = ['title', 'author__name']

请求示例:

GET /api/books/?search=python

OrderingFilter

允许通过 URL 参数排序:

from rest_framework import filters

class BookViewSet(ModelViewSet):
    filter_backends = [filters.OrderingFilter]
    ordering_fields = ['published_date', 'title']

请求示例:

GET /api/books/?ordering=published_date

3. django-filter 扩展

更强大的过滤功能,支持多字段、范围、精确匹配等。

安装

pip install django-filter

配置

settings.py 添加:

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}

使用方法

定义 FilterSet:

import django_filters
from .models import Book

class BookFilter(django_filters.FilterSet):
    min_price = django_filters.NumberFilter(field_name="price", lookup_expr='gte')
    max_price = django_filters.NumberFilter(field_name="price", lookup_expr='lte')
    published_after = django_filters.DateFilter(field_name="published_date", lookup_expr='gte')

    class Meta:
        model = Book
        fields = ['author', 'min_price', 'max_price', 'published_after']

在 ViewSet 中使用:

from django_filters.rest_framework import DjangoFilterBackend

class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = BookFilter

请求示例:

GET /api/books/?author=Tom&min_price=10&published_after=2023-01-01

4. 常用过滤类型

  • 精确匹配:field=value
  • 范围过滤:field__gte=valuefield__lte=value
  • 模糊搜索:search=关键字
  • 排序:ordering=字段名

5. 总结

  • 内置过滤器适合简单场景
  • 推荐使用 django-filter 实现复杂过滤逻辑
  • 只需在 ViewSet 中配置即可实现强大的 API 数据筛选功能

如需更复杂的自定义过滤,可以继承 FilterSet 或自定义 filter_queryset 方法。

在 Django REST Framework(DRF)中,IsAuthenticated 是一个常用的权限类(permission class),用于控制 API 接口的访问权限。


6 权限控制

1. 作用

IsAuthenticated 权限类确保只有已认证的用户(登录用户或通过 Token 验证的用户)才能访问接口。未认证用户请求时会返回 401 Unauthorized。


2. 使用方法

在视图或视图集(ViewSet)中设置:

from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

class MyProtectedView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({'msg': '你已通过认证,可以访问此接口'})

在 ViewSet 中:

from rest_framework.viewsets import ModelViewSet

class BookViewSet(ModelViewSet):
    permission_classes = [IsAuthenticated]
    # ...其他配置...

也可以在全局配置(settings.py)中设置:

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

3. 认证方式

IsAuthenticated 支持多种认证方式,如 Session、Token、JWT 等。只要用户通过认证,接口即可访问。


4. 典型返回

  • 已认证用户:正常返回数据
  • 未认证用户:返回 401 状态码和错误信息

5. 适用场景

适用于需要保护的接口,如用户信息、订单、个人数据等,防止未登录用户访问。


总结
IsAuthenticated 是 DRF 中最常用的权限控制方式之一,确保接口安全,只允许认证用户访问。