P11 Django-DRF(ModelViewSet)、路由组件(DefaultRouter)和自定义函数

ModelViewSet 是什么

ModelViewSet 是 Django REST framework 提供的一个视图集类,它封装了常见的模型操作方法。

它继承自GenericViewSetListModelMixinRetrieveModelMixinCreateModelMixinUpdateModelMixinDestoryModelMixin

所以,在使用ModelViewSet定义API时,我们只需要套用模板即可。

视图集类不再实现get()、post()、put()、delete()方法,而是实现动作 action。 如 list()、retrieve()、create()、update()、destory()

知识点
请求
url
特点

GenericViewSet

提供一组通用的视图方法,方便实现特定功能

ListModelMixin

get

127.0.0.1:8000/path/

提供 list 方法,用于获取资源列表

RetrieveModelMixin

get

127.0.0.1:8000/path/{1}/

提供 retrieve 方法,用于获取单个资源的详细信息

CreateModelMixin

post

127.0.0.1:8000/path/

提供 create 方法,用于创建资源

UpdateModelMixin

put

127.0.0.1:8000/path/{1}/

提供 update 方法,用于更新资源

DestroyModelMixin

detete

127.0.0.1:8000/path/{1}/

提供 destroy 方法,用于删除资源

自定义

get/post

127.0.0.1:8000/path/自定义

用户自定义方法/函数

  这些技术知识点可以配合使用,帮助我们快速构建出具有 CRUD 功能的 Web 应用,并且遵循了 Django 框架的惯例和最佳实践。它们的应用场景包括博客系统、电商平台、社交网络等各种类型的 Web 应用。通过使用这些技术知识点,我们能够提高开发效率,减少重复的代码编写工作,并且保证代码的一致性和可维护性。

如何使用 ModelViewSet

假设定义了模型 GoodsCategory 和序列化器 GoodsCategorySerilizer

models.py 文件中定义模型

from django.db.models import *


# Create your models here.
## 产品分类表
class GoodsCategory(Model):
    """产品分类"""

    name = CharField(max_length=64, verbose_name='分类名称')
    remark = CharField(max_length=64, null=True, verbose_name='备注', blank=True)

serializer.py 文件中定义序列化器

from rest_framework.serializers import *
from .models import *


class GoodsCategorySerilizer(ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = '__all__'

创建 ModelViewSet

设置 queryset 属性为要查询的对象集合,并设置 serializer_class 属性为对应的序列化器类。

views.py 中定义ModelViewSet

from rest_framework.viewsets import ModelViewSet
from .models import *
from .serializer import *


class GoodsCategoryViewSet(ModelViewSet):
    # 指定查询集(用到的数据)
    queryset = GoodsCategory.objects.all()
    # 指定查询集用到的序列化容器
    serializer_class = GoodsCategorySerializer

这样我们就定义好了API视图集,这个GoodsCategoryViewSet将提供 listcreateretrieveupdatedestroy 操作。

Django-DRF 路由组件

路由组件是什么?

  DefaultRouter是Django REST framework中提供的一个路由器类,用于自动生成URL路由。

  路由器是将URL与视图函数或视图集关联起来的一种机制。Django REST framework的路由器通过简单的配置可以自动生成标准的URL路由,从而减少了手动编写URL路由的工作量。

urlpatterns 变量的语法

urlpatterns 应该是url() 实例的一个Python 列表。

DefaultRouter的使用方法

urls.py

from django.contrib import admin
from django.urls import path
from apps.erp_test.views import *

from rest_framework import routers

router = routers.DefaultRouter()
router.register('GoodsCategory', GoodsCategoryViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('filtergoodscategory/', FilterGoodsCategory),
    path('insertgoodscategory/', InsertGoodsCategory),
    path('filtergoodscategoryapi/', FilterGoodsCategoryAPI.as_view()),
    path('getgoods/', GetGoods.as_view()),
]


urlpatterns += router.urls

  使用routers.DefaultRouter()​创建了一个默认的路由器对象,并使用router.register()​方法注册了一个视图集,GoodsCategoryViewSet​。这样可以自动为这个视图集生成对应的URL路由,并将其添加到urlpatterns​中。

设置路由

urls.py 中配置urlpatterns,使其指向我们的API视图集

from rest_framework import routers

# 创建DefaultRouter对象,用于生成路由
router = routers.DefaultRouter()
# 将视图集注册到路由器上,字符串里的是URL路径的前缀
router.register('GoodsCategory', GoodsCategoryViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

在该文件中,我们创建一个默认的Router,然后注册我们的GoodsCategoryViewSet。Router负责处理请求转到适当的视图。

这样,我们就可以通过API进行查询、创建、更新和删除操作。

请求的接口包括

url

请求

操作

http://127.0.0.1:8000/GoodsCategory

GET

获取所有对象

http://127.0.0.1:8000/GoodsCategory/

GET

获取所有对象

http://127.0.0.1:8000/GoodsCategory/2

GET

获取 id 为 2 的对象详细信息

http://127.0.0.1:8000/GoodsCategory/2/

GET

获取 id 为 2 的对象详细信息

http://127.0.0.1:8000/GoodsCategory/

POST

创建对象

http://127.0.0.1:8000/GoodsCategory/2/

DELETE

删除 id 为 2 的对象

http://127.0.0.1:8000/GoodsCategory/2/

PUT

修改 id 为 2 的对象

通过 Postman 测试

首先启动server

python manager.py runserver

获取所有对象

GET 请求

http://127.0.0.1:8000/GoodsCategory 或 http://127.0.0.1:8000/GoodsCategory/

从测试的结果选择一个id进行获取

获取指定 id 的对象

获取 id 为 13 的对象

GET 请求

http://127.0.0.1:8000/GoodsCategory/13 或 http://127.0.0.1:8000/GoodsCategory/13/

如果尝试获取GoodCategory中不含有的 id,则返回"未找到"

创建对象

创建name=水果remark=水果的对象

POST 请求

http://127.0.0.1:8000/GoodsCategory/

删除对象

获取 id 为 15 的对象

DELETE 请求

http://127.0.0.1:8000/GoodsCategory/15/

删除 id 不存在的对象,则返回"未找到"

修改对象

PUT 请求

http://127.0.0.1:8000/GoodsCategory/9/

修改 id 为 9 的对象

Django-DRF 自定义函数

自定义函数是什么

Django为视图提供了数个装饰器,用以支持相关的HTTP服务。django.views.decorators.http 包里的装饰器可以基于请求的方法来限制对视图的访问。若条件不满足会返回 django.http.HttpResponseNotAllowed。

require_http_methods(request_method_list)[source]

如何使用

导入action

from rest_framework.decorators import action

@action 是 Django REST framework 中的一个装饰器,用于将自定义函数转换为视图集的一个动作。@action 装饰器提供了一种定义自定义函数的方式,这些函数并不直接对应于标准的 CRUD 操作(Create-Read-Update-Delete),而是实现一些其他的自定义行为或业务逻辑。 “ @action 装饰器”用于在 ViewSet 中创建自定义动作(custom action),为 ViewSet 提供了更灵活应用且 @action 只在ViewSet视图集中生效。视图集中附加action装饰器可接收两个参数:

(1)methods: 声明该action对应的请求方式。

(2)detail: True/False声明该action的路径是否是action对应的请求方式。

views.py

class GoodsCategoryViewSet(ModelViewSet):
    # 指定查询集(用到的数据)
    queryset = GoodsCategory.objects.all()
    # 指定查询集用到的序列化容器
    serializer_class = GoodsCategorySerializer

    @action(detail=False, methods=['get'])
    def latest(self, request):
        latest_obj = GoodsCategory.objects.latest('id')
        print(latest_obj)
        return Response("helllo 你调用了自定义的函数")


    @action(detail=False, methods=['get','post'])
    def delete_example(self, request):
        name = request.data.get('name')
        # 删除名称为 'name' 的商品
        categories_to_delete = GoodsCategory.objects.filter(name=name)
        # 使用delete()方法删除对象
        deleted_count= categories_to_delete.delete()
        print(f"Deleted {deleted_count} categories.")      

    @action(detail=False, methods=['get','post'])
    def create_example(self, request):
        name = request.data.get('name')
            # 使用create()方法创建新的商品分类对象
        created_category = GoodsCategory.objects.create(name)
        print("Created category:", created_category)   

  其中,detail=False 表示该动作不需要处理单个对象,而是处理整个集合;

  被 @action 装饰的函数需要作为方法定义在视图集类中,并且在使用 router.register() 注册视图集时,需要指定 basename 参数,以确保该动作的 URL 能够正确映射到视图集。

最后更新于