Python全栈开发-第5章Django REST框架
第二篇 · Web开发与自动化🏗️ 第5章 Django REST框架用成熟的全功能框架构建企业级API5.1 Django REST速成项目创建、Model与Serializer入门Django REST Framework – 企业级API的"瑞士军刀"如果说FastAPI是一把锋利的手术刀——小巧精准,那Django REST Framework(DRF)就是一把瑞士军刀——功能齐全,开箱即用。DRF在Django的基础上添加了构建API所需的一切:ORM:Django自带强大的数据库操作层,支持多种数据库Admin后台:自动生成管理后台,数据增删改查零代码认证系统:内置Session、Token、Basic等多种认证方式序列化器:类似Pydantic,但功能更加丰富浏览器界面:自带可浏览的API界面,方便调试DRF特别适合需要快速搭建完整Web应用(不仅是API)的项目,比如内容管理系统、电商平台、企业内部系统等。# pip install django djangorestframework# ========== 项目结构 ==========# myproject/# manage.py# myproject/# settings.py# urls.py# products/# models.py# serializers.py# views.py# urls.py# ========== settings.py 关键配置 ==========INSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','rest_framework',# 添加DRF'products',# 添加我们的app]REST_FRAMEWORK={'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination','PAGE_SIZE':10,}# ========== products/models.py ==========fromdjango.dbimportmodelsclassCategory(models.Model):"""商品分类"""name=models.CharField(max_length=100,verbose_name="分类名称")description=models.TextField(blank=True,verbose_name="描述")created_at=models.DateTimeField(auto_now_add=True)classMeta:verbose_name_plural="分类"def__str__(self):returnself.nameclassProduct(models.Model):"""商品模型"""name=models.CharField(max_length=200,verbose_name="商品名称")category=models.ForeignKey(Category,on_delete=models.CASCADE,related_name="products",verbose_name="分类")price=models.DecimalField(max_digits=10,decimal_places=2,verbose_name="价格")stock=models.IntegerField(default=0,verbose_name="库存")description=models.TextField(blank=True,verbose_name="商品描述")is_active=models.BooleanField(default=True,verbose_name="是否上架")created_at=models.DateTimeField(auto_now_add=True)updated_at=models.DateTimeField(auto_now=True)classMeta:ordering=['-created_at']# 默认按创建时间倒序def__str__(self):returnf"{self.name}- Y{self.price}"# ========== products/serializers.py ==========fromrest_frameworkimportserializersfrom.modelsimportCategory,ProductclassCategorySerializer(serializers.ModelSerializer):"""分类序列化器"""product_count=serializers.SerializerMethodField()classMeta:model=Category fields=['id','name','description','product_count']defget_product_count(self,obj):returnobj.products.count()classProductSerializer(serializers.ModelSerializer):"""商品序列化器"""category_name=serializers.CharField(source='category.name',read_only=True)classMeta:model=Product fields=['id','name','category','category_name','price','stock','description','is_active','created_at','updated_at']read_only_fields=['created_at','updated_at']# 自定义验证:价格必须大于0defvalidate_price(self,value):ifvalue=0:raiseserializers.ValidationError("价格必须大于0")returnvalue# 自定义验证:库存不能为负数defvalidate_stock(self,value):ifvalue0:raiseserializers.ValidationError("库存不能为负数")returnvalue# ========== products/views.py ==========fromrest_frameworkimportgenericsfrom.modelsimportProductfrom.serializersimportProductSerializerclassProductListCreateView(generics.ListCreateAPIView):"""商品列表(GET)和创建(POST)"""queryset=Product.objects.filter(is_active=True)serializer_class=ProductSerializerclassProductDetailView(generics.RetrieveUpdateDestroyAPIView):"""商品详情(GET)、更新(PUT)和删除(DELETE)"""queryset=Product.objects.all()serializer_class=ProductSerializer# 创建项目命令:# django-admin startproject myproject# cd myproject python manage.py startapp products# python manage.py makemigrations# python manage.py migrate# python manage.py runserver💡 技巧Django项目的启动流程:django-admin startproject 创建项目骨架python manage.py startapp 创建应用在settings.py中注册app和DRF定义Model后运行 makemigrations + migrate 创建数据库表python manage.py runserver 启动开发服务器DRF自带的浏览器界面(访问API地址即可看到)是非常好的调试工具,善用它!🔑 核心要点核心知识点:Django项目由一个project和多个app组成,每个app负责一个功能模块Model定义数据库表结构,Django自动生成SQL并管理迁移ModelSerializer自动根据Model生成序列化器,包含验证和序列化逻辑source 参数可以访问关联对象的属性(如 category.name)generics 模块提供通用的视图类,几行代码即可实现CRUDvalidate_ 前缀的方法用于自定义字段验证逻辑🧪 随堂测验在DRF的ModelSerializer中,Meta类的 fields 属性的作用是什么?A. 定义数据库表的字段B. 指定序列化器包含哪些字段,控制输入输出的数据格式C. 设置字段的验证规则D. 定义API的路由路径答案解析:ModelSerializer的Meta.fields 指定了序列化器在序列化(输出)和反序列化(输入)时包含哪些字段。它控制着API返回的JSON结构以及接受哪些字段作为输入。数据库字段由Model定义,验证规则由validate_方法定义,路由由urls.py定义。5.2 ViewSet与路由用ModelViewSet和Router简化CRUDViewSet – 一个类搞定所有操作在上一课中,我们用了两个视图类(ListCreateAPIView和RetrieveUpdateDestroyAPIView)来实现商品的CRUD。但DRF有个更强大的工具——ViewSet,它能让你用一个类定义所有操作(list、create、retrieve、update、destroy),然后由Router自动生成所有URL。这就像自动档汽车:你只需要告诉它"我要前进"(定义操作),它自动帮你换挡、踩油门、控制方向(生成URL、映射HTTP方法)。配合过滤和搜索功能,ViewSet能让你用极少的代码实现功能强大的API。# pip install django-filter (过滤功能需要额外安装)# ========== products/views.py ==========fromrest_frameworkimportviewsets,filtersfromdjango_filters.rest_frameworkimportDjangoFilterBackendfrom.modelsimportProduct,Categoryfrom.serializersimportProductSerializer,CategorySerializerclassProductViewSet(viewsets.ModelViewSet):""" 商品ViewSet -- 一个类提供完整的CRUD操作 list: GET /api/products/ create: POST /api/products/ retrieve: GET /api/products/{pk}/ update: PUT /api/products/{pk}/ partial_update: PATCH /api/products/{pk}/ destroy: DELETE /api/products/{pk}/ """queryset=Product.objects.select_related('category').all()serializer_class=ProductSerializer# 过滤后端:支持按字段过滤filter_backends=[DjangoFilterBackend,# 精确过滤filters.SearchFilter,# 搜索filters.OrderingFilter,# 排序]# 可过滤的字段filterset_fields=['category','is_active']# 可搜索的字段(支持模糊匹配)search_fields=['name','description']# 可排序的字段ordering_fields=['price','created_at','stock']ordering=['-created_at']# 默认排序defget_queryset(self):"""重写queryset以支持价格范围过滤"""queryset=super().get_queryset()min_price=self.request.query_params.get('min_price')max_price=self.request.query_params.get('max_price')ifmin_price:queryset=queryset.filter(price__gte=min_price)ifmax_price:queryset=queryset.filter(price__lte=max_price)returnquerysetclassCategoryViewSet(viewsets.ModelViewSet)