ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

从零搭建 RESTful API 服务:DRF 开发指南与 JWT 认证实战

从零搭建 RESTful API 服务:DRF 开发指南与 JWT 认证实战 从零搭建 RESTful API 服务DRF 开发指南与 JWT 认证实战【免费下载链接】Python-100-DaysPython - 100天从新手到大师项目地址: https://gitcode.com/GitHub_Trending/py/Python-100-Days在 Python-100-Days 项目里DRF 开发指南相关的章节覆盖了 RESTful API 从零搭建的完整路径资源怎么规划、DRF 序列化器配置怎么写、JWT 认证流程如何跑通直到接口文档的规范交付。你跟着本文走一遍就能亲手做出一个带认证、分页、过滤和文档的博客 API并且知道每一步为什么这么做。一条博客 API 的完整旅程假设你要给前端提供查看某篇文章及其评论的能力。用户点击页面的瞬间发生的事是这样的浏览器发出GET /api/blogs/1/请求请求穿过 Django 的中间件被 URL 分发器转给对应的视图DRF 在这里接手先做认证你是谁、再做权限判断你能不能干这事视图取出模型数据交给序列化器转成 JSON响应原路返回前端拿到结果渲染页面。理解这条链路非常重要以后接口出任何问题——401、403、404、字段缺失——你都能快速定位到是认证、权限、路由、视图还是序列化哪一环出的事而不是两眼一抹黑地猜。安装 DRF 并配置全局默认值在终端执行安装命令把rest_framework注册进INSTALLED_APPSpip install djangorestframeworkINSTALLED_APPS [ # ...其他应用 rest_framework, ]然后在配置文件的REST_FRAMEWORK字典里设默认值。 这些默认值是全项目的底线单个视图随时可以用permission_classes、pagination_class等属性覆盖但覆盖是少数情况绝大多数接口应该沿用统一策略。配置项作用DEFAULT_AUTHENTICATION_CLASSES默认认证方式含SessionAuthentication基于 session、TokenAuthentication、BasicAuthenticationDEFAULT_PERMISSION_CLASSES默认权限如AllowAny、IsAuthenticated、IsAdminUserDEFAULT_PAGINATION_CLASS与PAGE_SIZE列表接口的默认分页器与每页条数EXCEPTION_HANDLER统一异常出口定制错误响应格式在这里改一个适合博客场景的起步配置REST_FRAMEWORK { DEFAULT_AUTHENTICATION_CLASSES: [ rest_framework.authentication.SessionAuthentication, ], DEFAULT_PERMISSION_CLASSES: [ rest_framework.permissions.AllowAny, ], DEFAULT_PAGINATION_CLASS: rest_framework.pagination.PageNumberPagination, PAGE_SIZE: 10, }序列化器给前端翻译模型字段前端、App、其他服务消费的都是 JSON而你的数据躺在 Django 模型里。两者之间需要一个翻译官——这就是 DRF 序列化器serializer它负责把模型实例转成可 JSON 化的字典同时反过来做输入校验。绝大多数情况下继承ModelSerializer并声明Meta就够了。注意fields要显式列出__all__会把模型里每个字段都暴露出去密码、内部计数这类字段一旦漏出去就是事故。class BlogSerializer(serializers.ModelSerializer): class Meta: model Blog fields (id, title, summary, content, pub_date)序列化时机是在视图里单个对象直接传列表则加manyTrue。返回结构也固定.data拿到字典交给Response就变成 JSON 响应。函数视图博客详情接口DRF 支持两种写法函数视图FBV和类视图CBV。函数视图最直观api_view装饰器声明允许的 HTTP 方法函数体想怎么写就怎么写适合逻辑个性化的接口。下面是一个博客详情接口同时演示了 404 的正确处理方式api_view([GET]) def blog_detail(request, blog_id): try: blog Blog.objects.get(pkblog_id) except Blog.DoesNotExist: return Response(statusstatus.HTTP_404_NOT_FOUND) return Response(BlogSerializer(blog).data)⚠️ 注意一个常见误区查不到对象就继续往下走、返回一串None前端会很难受。资源不存在就该返回 404这是 HTTP 语义的基本约定。类视图与嵌套路由评论接口一次配齐当接口是标准的列表 / 详情 / 创建套路时用类视图更省。ModelViewSet一次性给你list、retrieve、create、update、destroy全套动作你只需声明queryset和serializer_class如果只要读接口用ReadOnlyModelViewSet更克制。评论是博客的子资源放在blog/{blog_pk}/comments/下面。用DefaultRouter注册嵌套路由评论的挂在哪个博客下由路径参数直接给出class BlogViewSet(ReadOnlyModelViewSet): queryset Blog.objects.all() serializer_class BlogSerializer permission_classes [permissions.IsAuthenticatedOrReadOnly] class CommentSerializer(serializers.ModelSerializer): class Meta: model Comment fields (id, content, pub_date) def get_queryset(self): return Comment.objects.filter(blog_idself.kwargs[blog_pk]) action(detailFalse, methods[get, post]) def comments(self, request, blog_pkNone): # GET 返回该博客的评论POST 创建新评论此处省略分支细节 ... class CommentViewSet(ModelViewSet): serializer_class BlogViewSet.CommentSerializer queryset Comment.objects.none() def get_queryset(self): return Comment.objects.filter(blog_idself.kwargs[blog_pk]) def perform_create(self, serializer): serializer.save(blog_idself.kwargs[blog_pk])router DefaultRouter() router.register(blogs, BlogViewSet) router.register(rblogs/(?Pblog_pk\d)/comments, CommentViewSet, basenameblog-comment) urlpatterns router.urls几个要点值得记住权限写在视集上IsAuthenticatedOrReadOnly的语义是——GET等安全方法人人可读POST/PUT/DELETE必须登录。这正符合内容公开、评论需登录的业务诉求。评论挂在博客路径下创建时无需用户再传一次blog_id从路径取杜绝了评论写错博客这种 bug。ModelViewSet必须配合路由器注册basename在存在歧义时指定一下更稳。注册完成后用浏览器访问http://127.0.0.1:8000/api/DRF 自带一套可交互的接口页面能直接看到每个端点并手动发请求。 开发早期用它联调非常方便前端同学也能在上面试数据JWT 令牌怎么签发和校验session 认证有个扩展难题服务端必须保存会话对象多机部署时还要靠 Redis 之类共享存储。而 token 方案把状态挪到了客户端——用户登录后拿到令牌之后每次请求都带着它服务端只验签、不存状态加机器就能扩容。JWTJSON Web Token开放标准 RFC 7519由三段组成段与段之间用.连接部分内容用途头部{alg: HS256, typ: JWT}声明签名算法与类型载荷用户标识、exp过期时间可加自定义字段承载实际数据签名用服务器端密钥对前两段做 HMAC 摘要防伪造、防篡改完整 JWT 认证流程在 Python-100-Days 项目的 54.RESTful架构和DRF入门 中有系统讲解落地时用pip install pyjwt装上 PyJWT 即可签发登录成功后把用户 ID、过期时间等放进载荷用settings.SECRET_KEY编码成令牌返回给前端存储前端存入localStorage或sessionStorage之后每个请求都通过自定义请求头约定为Authorization携带校验服务端解码验签令牌过期或无效统一返回 401前端收到 401 就跳回登录页。两个提醒密钥只能留在服务端绝不能下发给客户端令牌一旦签发、在过期前无法作废所以有效期要设得短一些敏感操作另加二次验证。接口文档规范联调之前先把契约写清楚接口写好了前端怎么知道怎么调靠一份清晰的接口文档。项目里 94.网络API接口设计 推荐用 RAP2、YAPI 这类工具管理文档核心是一份契约。以博客详情接口为例文档应包含项目约定URL 与方法GET /api/blogs/{id}/路径参数id整数必填权限无需登录成功响应200正文为博客对象字段与序列化器一致失败响应404博客不存在401token 过期仅需认证接口分页接口的响应结构也值得写进文档DRF 的PageNumberPagination默认返回count总数、next/previous翻页地址和results当前页数据四个键。 实际项目里建议再约定一个统一信封成功时业务字段外附code: 0失败时code非零并配message让前端用一套逻辑处理所有异常。契约一旦双方确认后端改字段就必须同步改文档——这是避免联调扯皮最便宜的办法。新手最容易踩的 5 个坑fields __all__顺手一写敏感字段直接裸露。永远显式列字段。查不到就返回 None应该返回 404让客户端明确知道资源不存在。部分更新用了 PUTPUT 语义是全量替换只改几个字段请用 PATCH。默认权限没想清楚全局AllowAny意味着所有写接口也是公开的创建类接口记得收紧。跨域忘了配前后端分离必然跨域接入django-cors-headers并按来源白名单配置别图省事写*。下一步往哪走API 版本控制用 URL 前缀或请求头版本策略让老客户端不被破坏限流与节流给匿名/认证用户配置不同的频率上限防刷接口异步任务导出、通知这类慢操作交给 Celery 处理性能监控与日志记录慢查询给热点接口加缓存并盯紧命中率RESTful 架构与 DRF 的更多细节可以回看项目中的 55.RESTful架构和DRF进阶里面还有数据筛选django-filter和游标分页的完整写法。【免费下载链接】Python-100-DaysPython - 100天从新手到大师项目地址: https://gitcode.com/GitHub_Trending/py/Python-100-Days创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表