如何用Django REST Framework快速生成一套完整的API接口

访客 全栈框架 1

本文目录导读:

  1. 基础环境搭建
  2. 快速创建模型(Model)
  3. 创建序列化器(Serializer)
  4. 创建视图(View)
  5. 配置路由(URL)
  6. 高级特性集成
  7. 运行和测试
  8. 自定义API行为

我来详细介绍如何使用Django REST Framework (DRF) 快速生成完整的API接口。

基础环境搭建

安装依赖

pip install django
pip install djangorestframework
pip install django-filter  # 过滤支持
pip install django-cors-headers  # CORS支持

创建项目和APP

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

配置settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'django_filters',
    'corsheaders',
    'api',  # 你的APP
]
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # 放在最前面
    # ... 其他中间件
]
# REST Framework配置
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ],
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10,
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
        'rest_framework.filters.OrderingFilter',
    ],
}
# CORS配置
CORS_ALLOW_ALL_ORIGINS = True  # 开发环境使用

快速创建模型(Model)

models.py

from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    class Meta:
        verbose_name_plural = "Categories"
    def __str__(self):
        return self.name
class Article(models.Model):
    STATUS_CHOICES = [
        ('draft', 'Draft'),
        ('published', 'Published'),
        ('archived', 'Archived'),
    ]
    = models.CharField(max_length=200)
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='articles')
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='articles')
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    class Meta:
        ordering = ['-created_at']
    def __str__(self):
        return self.title

创建序列化器(Serializer)

serializers.py

from rest_framework import serializers
from .models import Category, Article
from django.contrib.auth.models import User
class CategorySerializer(serializers.ModelSerializer):
    article_count = serializers.IntegerField(read_only=True)
    class Meta:
        model = Category
        fields = ['id', 'name', 'description', 'created_at', 'article_count']
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email']
class ArticleSerializer(serializers.ModelSerializer):
    author_detail = UserSerializer(source='author', read_only=True)
    category_name = serializers.CharField(source='category.name', read_only=True)
    class Meta:
        model = Article
        fields = [
            'id', 'title', 'content', 'author', 'author_detail',
            'category', 'category_name', 'status',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['author', 'created_at', 'updated_at']
    def validate_title(self, value):
        if len(value) < 10:
            raise serializers.ValidationError("标题至少10个字符")
        return value

创建视图(View)

views.py - 使用ViewSet(最快速的方式)

from rest_framework import viewsets, permissions, filters, status
from rest_framework.decorators import action
from rest_framework.response import Response
from django_filters.rest_framework import DjangoFilterBackend
from .models import Category, Article
from .serializers import CategorySerializer, ArticleSerializer
class CategoryViewSet(viewsets.ModelViewSet):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    filterset_fields = ['name']
    search_fields = ['name', 'description']
    @action(detail=True, methods=['get'])
    def articles(self, request, pk=None):
        category = self.get_object()
        articles = Article.objects.filter(category=category)
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)
class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['status', 'category', 'author']
    search_fields = ['title', 'content']
    ordering_fields = ['created_at', 'updated_at', 'title']
    ordering = ['-created_at']
    def perform_create(self, serializer):
        serializer.save(author=self.request.user)
    @action(detail=True, methods=['post'])
    def publish(self, request, pk=None):
        article = self.get_object()
        article.status = 'published'
        article.save()
        return Response({'status': 'published'})
    @action(detail=False, methods=['get'])
    def my_articles(self, request):
        articles = Article.objects.filter(author=request.user)
        page = self.paginate_queryset(articles)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(articles, many=True)
        return Response(serializer.data)

配置路由(URL)

urls.py

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import CategoryViewSet, ArticleViewSet
router = DefaultRouter()
router.register(r'categories', CategoryViewSet)
router.register(r'articles', ArticleViewSet)
urlpatterns = [
    path('api/', include(router.urls)),
    path('api-auth/', include('rest_framework.urls')),  # DRF登录界面
]

高级特性集成

添加认证和权限

# permissions.py
from rest_framework import permissions
class IsAuthorOrReadOnly(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True
        return obj.author == request.user

使用mixins组合不同API

from rest_framework import mixins, generics
class CreateListCategoryView(mixins.CreateModelMixin,
                              mixins.ListModelMixin,
                              generics.GenericAPIView):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

添加API版本控制

# urls.py
from django.urls import path, include
urlpatterns = [
    path('api/v1/', include('api.urls_v1')),
    path('api/v2/', include('api.urls_v2')),
]

运行和测试

迁移数据库

python manage.py makemigrations
python manage.py migrate

创建超级用户

python manage.py createsuperuser

运行服务器

python manage.py runserver

访问API

  • 浏览API: http://localhost:8000/api/
  • 文章列表: GET http://localhost:8000/api/articles/
  • 创建文章: POST http://localhost:8000/api/articles/
  • 文章详情: GET http://localhost:8000/api/articles/1/
  • 更新文章: PUT http://localhost:8000/api/articles/1/
  • 删除文章: DELETE http://localhost:8000/api/articles/1/
  • 过滤文章: GET http://localhost:8000/api/articles/?status=published
  • 搜索文章: GET http://localhost:8000/api/articles/?search=django
  • 排序文章: GET http://localhost:8000/api/articles/?ordering=-created_at

自定义API行为

自定义序列化器

class ArticleDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = '__all__'
        depth = 1  # 自动嵌套关联对象
class ArticleListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ['id', 'title', 'status', 'created_at']

在不同action使用不同序列化器

class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    def get_serializer_class(self):
        if self.action == 'list':
            return ArticleListSerializer
        elif self.action == 'retrieve':
            return ArticleDetailSerializer
        return ArticleSerializer

这样你就拥有了一个功能完整的REST API接口,支持CRUD操作、过滤、搜索、排序、分页、认证等功能。

标签: 模型序列化器 接口自动生成

抱歉,评论功能暂时关闭!