Python-100-Days:3 步搭好一个规范 RESTful API,DRF 全流程实战
【免费下载链接】Python-100-DaysPython - 100天从新手到大师项目地址: https://gitcode.com/GitHub_Trending/py/Python-100-Days
刚学完 Python 基础、第一次接后端 API 需求时,RESTful 架构、序列化器、JWT 这些词很容易让人发懵。这篇文章基于 Python-100-Days 项目的 DRF 章节,用"评论系统"这个真实业务场景带你把接口从零跑通:配好环境、设计好接口、接入认证,三步走完就能交付一套规范的 RESTful API。
业务场景:给内容社区加一套评论接口
先说需求:你负责的内容社区要上线评论功能,前端需要一个接口拉评论列表、发新评论、删除违规评论。这类需求别把逻辑写死在页面里,抽成 API 后网页、App、小程序多端能直接复用同一套数据。下面按"能跑起来 → 设计清楚 → 安全闭环"的顺序推进。
5 分钟环境搭建:DRF 最小可用全局配置
DRF 是 Django 生态里做 RESTful API 的事实标准,装完加两段配置就能开工。
pip install djangorestframework# settings.py INSTALLED_APPS = [ # ...其余应用省略 'rest_framework', ] REST_FRAMEWORK = { 'PAGE_SIZE': 10, 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', 'rest_framework.authentication.SessionAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ] }全局默认权限设成IsAuthenticated,意味着每个接口默认都要登录,后续想放行某个接口再单独覆盖,比默认全公开安全得多。项目跑起来后,浏览器直接访问接口 URL,DRF 会给你一个可视化调试页,发请求、看响应不用切 Postman:
RESTful 接口命名规范:URI 是名词,动词交给 HTTP
写代码前先定好接口,这是新手和熟手的第一个分水岭。命名只有一条口诀:URI 只放名词,动作由 HTTP 方法表达。
| 方法 | 路径 | 语义 |
|---|---|---|
| GET | /api/orders/ | 拉取订单列表 |
| POST | /api/orders/ | 创建新订单 |
| GET | /api/orders/{id}/ | 查询单个订单 |
| PUT | /api/orders/{id}/ | 全量更新订单 |
| PATCH | /api/orders/{id}/ | 局部更新订单 |
| DELETE | /api/orders/{id}/ | 删除订单 |
对比一下/getOrderList、/deleteOrder这类写法:后者把动作塞进了 URL,方法语义丢失,前端调用也没法遵循统一约定。子资源同理,嵌套一层即可,比如GET /api/orders/{id}/comments/表示"某订单的评论列表"。
序列化器:模型到 JSON 的翻译官
模型对象不能直接丢给前端,序列化器负责双向翻译:出方向把Order实例变成 JSON,进方向把请求体校验回合法数据。用ModelSerializer只写 4 行核心代码,字段校验方法会自动被框架调用:
from rest_framework import serializers from .models import Order class OrderSerializer(serializers.ModelSerializer): class Meta: model = Order fields = ('id', 'amount', 'product_name', 'created_at') def validate_amount(self, value): if value <= 0: raise serializers.ValidationError('订单金额必须大于 0') return value💡 注意validate_字段名的命名约定——框架看到请求体里有amount就会调这个方法,抛出的ValidationError自动转成 400 响应,异常处理不用你操心。
视图选型:ModelViewSet 5 行代码搞定全套 CRUD
常规增删改查优先用ModelViewSet,五个动作(列表、详情、创建、更新、删除)它全部内置,你只需声明数据从哪来、怎么序列化:
from rest_framework.viewsets import ModelViewSet class OrderViewSet(ModelViewSet): queryset = Order.objects.all() serializer_class = OrderSerializer permission_classes = [IsAuthenticated]再配合路由器完成 URL 映射:
from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register('api/orders', OrderViewSet) urlpatterns += router.urls什么时候用基于函数的视图(FBV)?当你需要完全自定义请求处理流程、返回结构和 DRF 的默认套路不一致时,用@api_view装饰普通函数更自由。但 90% 的常规 CRUD,ViewSet 一行逻辑都不用写,别重复造轮子。
JWT 令牌认证流程:登录发一次,请求带一路
先看完整闭环:登录成功 → 服务端签发令牌 → 前端本地存储 → 之后每次请求携带令牌 → 服务端验签放行或拒绝。
图里 Client、Authorization Server、Resource Server 三者间的 A~F 六步,本质就是"先找认证方换令牌,再拿令牌找资源方要数据"。放到你的项目里:登录接口就是认证方,订单、评论接口都是资源方。
生成令牌(登录成功后执行):
import jwt from datetime import datetime, timedelta def generate_token(user): payload = { 'userid': user.id, 'exp': datetime.utcnow() + timedelta(days=1), } return jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256')校验令牌(受保护接口入口处执行):
def verify_token(token): try: return jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256']) except jwt.ExpiredSignatureError: return None # 令牌过期,返回 401 让前端重新登录 except jwt.InvalidTokenError: return None # 无效令牌,同样拒绝两个高频坑 ⚠️:
jwt.decode必须显式传algorithms参数,新版本 PyJWT 不传会直接报错,这是安全加固。- 过期和无效要分开捕获,前端拿到 401 能区分"去重新登录"还是"检查请求头"。
另外记住:JWT 在过期前无法主动作废,所以有效期别设太长,敏感操作(如改密码)要二次验证。
上线前检查:接口文档必含 4 项,过滤分页一步到位
接口写完不算完,前端拿到文档才能开工。每个接口的文档必须包含 4 项,缺一不可:
- 接口 URL 和请求方法
- 参数说明:类型、位置(路径/查询/请求体/请求头)、是否必填
- 响应体示例(成功和失败各一份)
- 错误码说明:401 未登录、403 无权限、404 不存在分别对应什么场景
列表接口的过滤和排序交给django-filter,在 ViewSet 上加三行属性:
class OrderViewSet(ModelViewSet): queryset = Order.objects.all() serializer_class = OrderSerializer filter_backends = [DjangoFilterBackend, OrderingFilter] filterset_fields = ['status'] ordering_fields = ['created_at', 'amount']这样?status=paid&ordering=-created_at这类查询参数自动生效。分页更省事:第二节全局配置里已经写好了PAGE_SIZE,所有列表接口自动返回分页结构,不需要逐个接口处理。
📌 完整接口文档的规范写法(含全局状态码约定、参数表格模板),可以对照 Day91-100/94.网络API接口设计.md 补全。
延伸路线
- API 版本控制:URL 里带
/api/v1/前缀,接口破坏性变更时新旧版本并存。 - 限流:用 DRF 内置 Throttle 按用户 + IP 维度控制请求频率。
- 异步任务:发通知、生成报表这类耗时操作丢给 Celery。
- 性能监控:记录每个请求的耗时和状态码,慢接口和 5xx 才能被及时发现。
- 继续深入:Day46-60/54.RESTful架构和DRF入门.md 里有基于 token 的完整登录实现可对照阅读。
【免费下载链接】Python-100-DaysPython - 100天从新手到大师项目地址: https://gitcode.com/GitHub_Trending/py/Python-100-Days
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考