DjangoRESTFramework入门教程:从零开始构建API

Django REST Framework 入门教程:从零开始构建 API

Django REST Framework (DRF) 是一个强大且灵活的工具包,用于构建 Web API。它基于 Django,简化了序列化、认证、权限控制等常见 API 开发任务。本教程将带你从零开始,一步步构建一个简单的 API。

1. 环境准备

在开始之前,确保你已经安装了以下软件:

  • Python (3.6+): 建议使用最新版本的 Python。
  • pip: Python 包管理工具。
  • 虚拟环境 (可选但强烈推荐): 使用 venvvirtualenv 创建隔离的开发环境。

创建虚拟环境 (可选):

```bash

使用 venv (Python 3 内置)

python3 -m venv .venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\activate # Windows

或者使用 virtualenv (需要先安装: pip install virtualenv)

virtualenv .venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\activate # Windows
```

安装 Django 和 DRF:

bash
pip install django djangorestframework

2. 创建 Django 项目和应用

创建 Django 项目:

bash
django-admin startproject myproject
cd myproject

创建 Django 应用 (例如 "books"):

bash
python manage.py startapp books

目录结构:

myproject/
├── manage.py
├── myproject/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── asgi.py
│ └── wsgi.py
└── books/
├── __init__.py
├── admin.py
├── apps.py
├── migrations/
│ └── __init__.py
├── models.py
├── tests.py
└── views.py

3. 定义模型 (Model)

books/models.py 中定义一个简单的 Book 模型:

```python
from django.db import models

class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
publication_date = models.DateField()
isbn = models.CharField(max_length=20, unique=True, blank=True, null=True) # ISBN 可以为空

def __str__(self):
    return self.title

```

4. 配置 Django 项目

将应用添加到 settings.pyINSTALLED_APPS 中:

```python

myproject/settings.py

INSTALLED_APPS = [
# ... 其他应用
'rest_framework',
'books',
]
```
添加rest_framework配置(可选)

```python

myproject/settings.py

REST_FRAMEWORK = {
# Use Django's standard django.contrib.auth permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
```

5. 创建序列化器 (Serializer)

序列化器负责将模型实例转换为 JSON(或其他格式)数据,以及将 JSON 数据反序列化为模型实例。

books/ 目录下创建 serializers.py 文件:

```python
from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = 'all' # 或者指定需要的字段: ['id', 'title', 'author', 'publication_date', 'isbn']
# exclude = ['some_field'] #排除某些字段

# 你可以在这里添加自定义字段或方法
# 例如,计算一个字段的值
#  extra_field = serializers.SerializerMethodField()
#  def get_extra_field(self, obj):
#        return obj.some_attribute * 2

``ModelSerializer类会自动根据模型定义生成序列化器字段。fields = 'all'` 表示包含模型中的所有字段。

6. 创建视图 (View)

DRF 提供了多种视图类,简化了 API 视图的编写。

books/views.py 中创建视图:

```python
from rest_framework import generics
from .models import Book
from .serializers import BookSerializer
from rest_framework import permissions # 引入权限模块
from rest_framework.pagination import PageNumberPagination

自定义分页类

class StandardResultsSetPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 1000

class BookListCreateView(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# permission_classes = [permissions.IsAuthenticatedOrReadOnly] # 认证用户可写,匿名用户只读。 也可以在setting中全局设置
pagination_class = StandardResultsSetPagination

class BookRetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# permission_classes = [permissions.IsAuthenticatedOrReadOnly]
# lookup_field = 'isbn' #如果主键不是id,可以在这里设置,例如通过isbn查找

更底层的写法,手动处理请求:

from rest_framework.views import APIView

from rest_framework.response import Response

from rest_framework import status

class BookListCreateView(APIView):

def get(self, request):

books = Book.objects.all()

serializer = BookSerializer(books, many=True)

return Response(serializer.data)

def post(self, request):

serializer = BookSerializer(data=request.data)

if serializer.is_valid():

serializer.save()

return Response(serializer.data, status=status.HTTP_201_CREATED)

return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

```

  • ListCreateAPIView: 用于处理列表 (GET) 和创建 (POST) 请求。
  • RetrieveUpdateDestroyAPIView: 用于处理单个对象的检索 (GET)、更新 (PUT/PATCH) 和删除 (DELETE) 请求。
  • queryset: 指定视图操作的模型对象集合。
  • serializer_class: 指定用于序列化和反序列化的序列化器。
  • permission_classes : 权限设置
  • pagination_class: 分页设置

7. 配置 URL

创建 books/urls.py 文件:

```python
from django.urls import path
from .views import BookListCreateView, BookRetrieveUpdateDestroyView

urlpatterns = [
path('books/', BookListCreateView.as_view(), name='book-list'),
path('books//', BookRetrieveUpdateDestroyView.as_view(), name='book-detail'), # 捕获主键
]
```

myproject/urls.py 中包含应用的 URL:

```python
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('books.urls')), # 包含 books 应用的 URL
]
```

8. 数据库迁移

运行以下命令创建数据库表:

bash
python manage.py makemigrations
python manage.py migrate

9. 运行开发服务器

bash
python manage.py runserver

现在,你可以通过以下 URL 访问 API:

  • http://127.0.0.1:8000/api/books/: 获取书籍列表 (GET) 或创建新书籍 (POST)。
  • http://127.0.0.1:8000/api/books/<pk>/: 获取、更新或删除指定 ID 的书籍 (GET, PUT, PATCH, DELETE)。 <pk> 是书籍的主键 (通常是 id)。

可以使用 Postman、curl 或浏览器等工具测试 API。

10. 测试 API (使用 Postman)

  1. GET 请求 (获取书籍列表):

    • URL: http://127.0.0.1:8000/api/books/
    • 方法: GET
    • 发送请求,你应该会看到一个空数组 (因为还没有创建任何书籍)。
  2. POST 请求 (创建书籍):

    • URL: http://127.0.0.1:8000/api/books/
    • 方法: POST
    • Headers:
      • Content-Type: application/json
    • Body (raw, JSON):

    json
    {
    "title": "The Lord of the Rings",
    "author": "J.R.R. Tolkien",
    "publication_date": "1954-07-29",
    "isbn": "978-0618640157"
    }

    • 发送请求,你应该会收到一个 201 Created 响应,包含新创建的书籍数据。
  3. GET 请求 (获取单个书籍):

    • URL: http://127.0.0.1:8000/api/books/1/ (假设你创建的第一本书的 ID 是 1)
    • 方法: GET
    • 发送请求,你应该会收到刚刚创建的书籍的详细信息。
  4. PUT/PATCH 请求 (更新书籍):

    • URL: http://127.0.0.1:8000/api/books/1/
    • 方法: PUT 或 PATCH (PUT 更新整个对象,PATCH 更新部分字段)
    • Headers:
      • Content-Type: application/json
    • Body (raw, JSON): (例如,修改标题)

    json
    {
    "title": "The Lord of the Rings (Revised Edition)"
    }

    • 发送请求,你应该会收到一个 200 OK 响应,包含更新后的书籍数据。
  5. DELETE 请求 (删除书籍):

    • URL: http://127.0.0.1:8000/api/books/1/
    • 方法: DELETE
    • 发送请求,你应该会收到一个 204 No Content 响应。

11. 进一步探索

这只是一个非常基础的入门教程。 DRF 还有很多高级功能,例如:

  • 认证 (Authentication): 支持多种认证方式,如 Session 认证、Token 认证、JWT 认证等。
  • 权限 (Permissions): 控制不同用户对 API 的访问权限。
  • 限流 (Throttling): 限制 API 请求频率,防止滥用。
  • 过滤 (Filtering): 允许客户端根据条件过滤数据。
  • 版本控制 (Versioning): 管理 API 的不同版本。
  • 可浏览的 API (Browsable API): DRF 提供了一个交互式的 Web 界面,方便查看和测试 API。
  • 文档生成 (Documentation): 可以使用工具 (如 Swagger/OpenAPI) 自动生成 API 文档。
  • 自定义序列化器字段和验证: 可以创建自定义的序列化器字段,进行更复杂的验证和数据转换。
  • 视图集 (ViewSets): 将相关的视图逻辑 (list, create, retrieve, update, destroy) 组合到一个类中。
  • 路由 Routers: 简化 URL 配置.
  • 测试 (Testing): DRF提供了用于测试API的工具

建议你阅读 DRF 的官方文档 (https://www.django-rest-framework.org/),深入了解这些功能。 通过本教程,你已经掌握了使用 Django REST Framework 构建 API 的基础知识。 不断练习和探索,你会发现 DRF 的强大和便捷!

THE END