从零到一:Python开发者如何用Django REST Framework打造企业级API
从零到一Python开发者如何用Django REST Framework打造企业级API【免费下载链接】Python-100-DaysPython - 100天从新手到大师项目地址: https://gitcode.com/GitHub_Trending/py/Python-100-Days想象一下这个场景你刚加入一家创业公司老板说我们需要一个API让移动端App能访问用户数据而你只有Python和Django的基础知识。别慌今天我就带你用Django REST FrameworkDRF这个神器从零开始构建一个完整的企业级REST API。为什么你的项目需要REST API我们先来看看传统Web开发和API开发的对比传统Web开发API开发服务器渲染HTML页面服务器返回JSON数据前后端代码混合前后端完全分离一个团队全包前端、移动端、后端团队分工协作难以支持多平台一套API支持Web、iOS、Android现在你知道为什么大厂都在用API了吧它让开发效率提升至少30%实战从Hello API到用户管理系统第一步搭建你的API游乐场先创建一个Django项目然后安装DRF# 创建项目 django-admin startproject api_project cd api_project # 创建用户管理应用 python manage.py startapp users # 安装DRF pip install djangorestframework修改settings.py让DRF加入你的项目# settings.py INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, rest_framework, # 添加这一行 users, # 你的应用 ] # DRF配置 REST_FRAMEWORK { DEFAULT_AUTHENTICATION_CLASSES: [ rest_framework.authentication.SessionAuthentication, rest_framework.authentication.TokenAuthentication, ], DEFAULT_PERMISSION_CLASSES: [ rest_framework.permissions.IsAuthenticatedOrReadOnly, ], DEFAULT_PAGINATION_CLASS: rest_framework.pagination.PageNumberPagination, PAGE_SIZE: 10 }第二步创建你的第一个API端点让我们从最简单的Hello API开始。在users/views.py中from rest_framework.decorators import api_view from rest_framework.response import Response api_view([GET]) def hello_api(request): 最简单的API端点 return Response({ message: 欢迎来到API世界, status: success, timestamp: timezone.now() })现在在urls.py中添加路由from django.urls import path from users.views import hello_api urlpatterns [ path(api/hello/, hello_api, namehello-api), ]启动服务器访问http://localhost:8000/api/hello/你会看到{ message: 欢迎来到API世界, status: success, timestamp: 2024-01-01T10:00:00Z }恭喜你的第一个API已经上线了。进阶构建完整的用户管理API模型设计不只是User模型在users/models.py中我们创建一个增强的用户模型from django.contrib.auth.models import AbstractUser from django.db import models class CustomUser(AbstractUser): 自定义用户模型 phone models.CharField(max_length15, blankTrue, nullTrue) avatar models.ImageField(upload_toavatars/, blankTrue, nullTrue) bio models.TextField(blankTrue, nullTrue) is_verified models.BooleanField(defaultFalse) created_at models.DateTimeField(auto_now_addTrue) updated_at models.DateTimeField(auto_nowTrue) class Meta: db_table custom_users verbose_name 用户 verbose_name_plural 用户管理 def __str__(self): return f{self.username} ({self.email})序列化器数据的变形金刚序列化器是DRF的核心它把数据库对象变成JSON也能把JSON变回数据库对象。在users/serializers.py中from rest_framework import serializers from django.contrib.auth.hashers import make_password from .models import CustomUser class UserSerializer(serializers.ModelSerializer): 用户序列化器 password serializers.CharField(write_onlyTrue) # 密码只写不读 confirm_password serializers.CharField(write_onlyTrue) # 确认密码 class Meta: model CustomUser fields [id, username, email, phone, password, confirm_password, bio, is_verified, created_at] def validate(self, data): 验证数据 if data[password] ! data[confirm_password]: raise serializers.ValidationError(两次输入的密码不一致) return data def create(self, validated_data): 创建用户时加密密码 validated_data.pop(confirm_password) # 移除确认密码字段 validated_data[password] make_password(validated_data[password]) return super().create(validated_data) def update(self, instance, validated_data): 更新用户信息 if password in validated_data: validated_data[password] make_password(validated_data[password]) return super().update(instance, validated_data)视图集一行代码搞定CRUDDRF最强大的功能之一就是ViewSet它能用极少的代码实现完整的CRUD操作from rest_framework import viewsets, permissions, filters from rest_framework.decorators import action from rest_framework.response import Response from django_filters.rest_framework import DjangoFilterBackend from .models import CustomUser from .serializers import UserSerializer class UserViewSet(viewsets.ModelViewSet): 用户视图集 queryset CustomUser.objects.all() serializer_class UserSerializer permission_classes [permissions.IsAuthenticated] filter_backends [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter] filterset_fields [is_verified, is_active] search_fields [username, email, phone] ordering_fields [created_at, username] action(detailFalse, methods[get]) def me(self, request): 获取当前用户信息 serializer self.get_serializer(request.user) return Response(serializer.data) action(detailFalse, methods[post]) def register(self, request): 用户注册 serializer self.get_serializer(datarequest.data) serializer.is_valid(raise_exceptionTrue) user serializer.save() return Response({ user_id: user.id, message: 注册成功, token: user.auth_token.key if hasattr(user, auth_token) else None }, status201) action(detailTrue, methods[post]) def change_password(self, request, pkNone): 修改密码 user self.get_object() old_password request.data.get(old_password) new_password request.data.get(new_password) if not user.check_password(old_password): return Response({error: 原密码错误}, status400) user.set_password(new_password) user.save() return Response({message: 密码修改成功})DRF的可视化调试界面DRF最酷的功能之一就是它自带的API调试界面。当你访问API端点时它会自动生成一个漂亮的Web界面这个界面不仅展示了API的响应数据还提供了实时测试API的功能查看请求/响应头信息在线填写表单提交数据查看API文档认证与安全保护你的APIJWT认证无状态的安全卫士在分布式系统中JWTJSON Web Token是最流行的认证方式。让我们看看它的结构JWT由三部分组成Header算法和令牌类型Payload用户信息和权限声明Signature签名验证完整性安装JWT支持pip install djangorestframework-simplejwt配置JWT认证# settings.py REST_FRAMEWORK { DEFAULT_AUTHENTICATION_CLASSES: [ rest_framework_simplejwt.authentication.JWTAuthentication, ], } # JWT配置 from datetime import timedelta SIMPLE_JWT { ACCESS_TOKEN_LIFETIME: timedelta(hours1), REFRESH_TOKEN_LIFETIME: timedelta(days7), ROTATE_REFRESH_TOKENS: True, BLACKLIST_AFTER_ROTATION: True, }权限控制谁可以做什么DRF提供了灵活的权限系统from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): 自定义权限只有所有者可以编辑 def has_object_permission(self, request, view, obj): # 读取权限允许任何请求 if request.method in permissions.SAFE_METHODS: return True # 写入权限只允许对象的所有者 return obj.owner request.user class IsAdminOrReadOnly(permissions.BasePermission): 管理员可以编辑其他人只能读取 def has_permission(self, request, view): if request.method in permissions.SAFE_METHODS: return True return request.user and request.user.is_staff高级技巧让你的API更强大1. 分页处理大量数据from rest_framework.pagination import PageNumberPagination class CustomPagination(PageNumberPagination): page_size 20 page_size_query_param page_size max_page_size 100 def get_paginated_response(self, data): return Response({ links: { next: self.get_next_link(), previous: self.get_previous_link() }, count: self.page.paginator.count, total_pages: self.page.paginator.num_pages, current_page: self.page.number, results: data })2. 缓存提升性能from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page from django.views.decorators.vary import vary_on_cookie class CachedUserViewSet(viewsets.ModelViewSet): 带缓存的用户视图集 queryset CustomUser.objects.all() serializer_class UserSerializer method_decorator(cache_page(60 * 15)) # 缓存15分钟 method_decorator(vary_on_cookie) def list(self, request, *args, **kwargs): return super().list(request, *args, **kwargs)3. 限流防止API被滥用REST_FRAMEWORK { DEFAULT_THROTTLE_CLASSES: [ rest_framework.throttling.AnonRateThrottle, # 匿名用户 rest_framework.throttling.UserRateThrottle, # 认证用户 ], DEFAULT_THROTTLE_RATES: { anon: 100/day, # 匿名用户每天100次 user: 1000/day, # 认证用户每天1000次 burst: 60/minute, # 突发请求限制 } }常见问题与解决方案问题1跨域请求被阻止解决方案安装django-cors-headerspip install django-cors-headers配置# settings.py INSTALLED_APPS [ corsheaders, ] MIDDLEWARE [ corsheaders.middleware.CorsMiddleware, django.middleware.common.CommonMiddleware, ] CORS_ALLOWED_ORIGINS [ http://localhost:3000, # React开发服务器 http://127.0.0.1:3000, ]问题2API响应慢优化建议使用select_related和prefetch_related减少数据库查询添加适当的索引使用缓存启用Gzip压缩# 优化查询示例 class OptimizedUserViewSet(viewsets.ModelViewSet): def get_queryset(self): return CustomUser.objects.select_related(profile).prefetch_related(groups)问题3API文档不完整使用DRF的自动文档生成from rest_framework.documentation import include_docs_urls urlpatterns [ path(docs/, include_docs_urls(titleAPI文档)), ]实战项目构建一个博客API让我们把所有知识整合起来构建一个完整的博客API# blog/models.py class Post(models.Model): title models.CharField(max_length200) content models.TextField() author models.ForeignKey(CustomUser, on_deletemodels.CASCADE) tags models.ManyToManyField(Tag) published models.BooleanField(defaultFalse) created_at models.DateTimeField(auto_now_addTrue) updated_at models.DateTimeField(auto_nowTrue) # blog/serializers.py class PostSerializer(serializers.ModelSerializer): author UserSerializer(read_onlyTrue) tags TagSerializer(manyTrue, read_onlyTrue) class Meta: model Post fields __all__ read_only_fields [author, created_at, updated_at] # blog/views.py class PostViewSet(viewsets.ModelViewSet): queryset Post.objects.filter(publishedTrue) serializer_class PostSerializer permission_classes [permissions.IsAuthenticatedOrReadOnly] def perform_create(self, serializer): serializer.save(authorself.request.user)总结API开发的思维导图RESTful API开发全流程 ├── 设计阶段 │ ├── 确定资源URI设计 │ ├── 定义HTTP方法 │ ├── 设计请求/响应格式 │ └── 规划认证授权 ├── 实现阶段 │ ├── 安装配置DRF │ ├── 创建模型和序列化器 │ ├── 编写视图和路由 │ ├── 实现认证授权 │ └── 添加分页过滤 ├── 优化阶段 │ ├── 性能优化缓存、索引 │ ├── 安全加固限流、验证 │ ├── 文档生成 │ └── 测试覆盖 └── 部署阶段 ├── 环境配置 ├── 监控告警 ├── 日志分析 └── 版本管理下一步学习路径掌握了DRF基础后你可以继续深入学习API版本管理- 如何优雅地升级API而不破坏现有客户端GraphQL vs REST- 什么时候该用GraphQLAPI网关- 大型系统的API治理微服务架构- 将API拆分成独立的微服务性能监控- 使用APM工具监控API性能记住好的API设计就像好的产品设计简单、直观、稳定。DRF提供了强大的工具但真正优秀的API设计需要你对业务有深刻理解。现在去创建你的第一个API吧提示本文基于Python-100-Days项目中的Day46-60内容更多实战案例和进阶技巧可以在项目的相关章节中找到。【免费下载链接】Python-100-DaysPython - 100天从新手到大师项目地址: https://gitcode.com/GitHub_Trending/py/Python-100-Days创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考