从入门到"精通"Django REST Framework-(一)

一、为什么使用 Django REST Framework?

  • 快速构建 API:通过 DRF 的封装类(如 APIViewModelSerializer)减少重复代码。
  • 功能丰富:内置认证、权限、分页、过滤等常用功能。
  • 标准化协议:严格遵循 RESTful 设计规范,适合前后端分离项目。

二、适用场景

  • 前后端分离项目(如为 Vue/React 提供数据接口)。
  • 移动应用(iOS/Android)后端 API。
  • 快速开发企业级数据管理后台。

三、实现一个简单接口

第 1 步:安装配置 DRF

  1. 安装 DRF
pip install djangorestframework
  1. 创建book应用
python manage.py startapp book
  1. **配置 **settings.py
# settings.py
INSTALLED_APPS = [
    # ...
    'rest_framework',          # 添加 DRF
    'your_app',                # 你的应用(需提前创建)book
]

REST_FRAMEWORK = {
    # 示例:全局权限配置(允许所有用户访问)
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ]
}

第 2 步:定义 Model 类

创建一个简单的 Book 模型:

# models.py
from django.db import models

class Book(models.Model):
    """
    书籍模型类
    用于表示系统中的书籍信息
    """
    
    # 书名字段:CharField 类型,最大长度100字符,必填项
    title = models.CharField(
        max_length=100, 
        verbose_name='书名',  # 在 Admin 后台显示为"书名"
        help_text='请输入书籍名称(最多100个字符)'  # 表单中的帮助提示
    )
    
    # 作者字段:CharField 类型,最大长度50字符,必填项
    author = models.CharField(
        max_length=50,
        verbose_name='作者',
        help_text='请输入作者姓名(最多50个字符)'
    )
    
    # 价格字段:DecimalField 类型,最大5位数(含2位小数)
    price = models.DecimalField(
        max_digits=5,          # 总位数(包括小数位)
        decimal_places=2,      # 小数位数
        verbose_name='价格',
        help_text='请输入价格(格式:99.99)'
    )

    def __str__(self):
        """
        定义对象的字符串表示形式
        在 Admin 后台和 Shell 中显示为书名
        """
        return self.title

    class Meta:
        """
        模型的元数据配置
        """
        verbose_name = '书籍'          # 单数形式显示名称(默认显示在 Admin 后台)
        verbose_name_plural = '书籍'   # 复数形式显示名称(避免自动加"s")
        ordering = ['-price']          # 默认按价格降序排序
        indexes = [
            models.Index(fields=['title'], name='title_idx'),  # 为书名字段创建索引
        ]

运行迁移命令

python manage.py makemigrations
python manage.py migrate

**第 3 步:使用基础 **Serializer

serializers.py手动定义序列化器字段:

# serializers.py
from rest_framework import serializers

class BookSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=100)
    author = serializers.CharField(max_length=50)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)

**第 4 步:使用视图类 **APIView

编写处理 GET 请求的视图:

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer

class BookListAPIView(APIView):
    def get(self, request):
        # 获取所有书籍数据
        books = Book.objects.all()
        # 序列化数据(many=True 表示处理多个对象)
        serializer = BookSerializer(books, many=True)
        # 返回 JSON 响应
        return Response(serializer.data)

第 5 步:配置路由

将视图映射到 URL:

# urls.py(应用级路由)
from django.urls import path
from .views import BookListAPIView

urlpatterns = [
    path('books/', BookListAPIView.as_view(), name='book-list'),
]

# urls.py(项目级路由)
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('your_app.urls')),  # 包含应用路由
]

第 6 步:测试 GET 请求

  1. 手动添加 Book 数据:启动Django Shell
python manage.py shell

执行添加代码

from your_app.models import Book  # 替换 your_app 为实际应用名

# 添加单条数据
Book.objects.create(
    title="Python编程", 
    author="John", 
    price=99.9
)

# 添加多条数据
Book.objects.create(title="Django实战", author="Alice", price=89.5)

验证数据

# 查询所有书籍
Book.objects.all()
  1. 启动开发服务器
python manage.py runserver
  1. 访问 API 端点
    • 浏览器或工具访问:http://localhost:8000/api/books/
    • 预期 JSON 响应:
[
    {
        "title": "Python编程",
        "author": "John",
        "price": "99.90"
    },
    {
        "title": "Django实战",
        "author": "Alice",
        "price": "89.50"
    }
]

四、核心代码总结

文件 代码片段 作用
settings.py INSTALLED_APPS += ['rest_framework'] 启用 DRF 功能
models.py class Book(models.Model): ... 定义数据模型
serializers.py class BookSerializer(...): ... 手动序列化数据
views.py class BookListAPIView(APIView): ... 处理 GET 请求逻辑
urls.py path('books/', BookListAPIView.as_view()) 路由映射
posted @ 2025-02-21 23:54  rxg456  阅读(97)  评论(0)    收藏  举报