visual studio网站开发教程,网站分享组件,软件开发项目管理的常识,网站群建设存在的问题之前我们的视图类可以继承GenericViewSet或者ModelViewSet#xff0c;我们不用再自定义通用的action方法#xff0c;但是有时候我们需要自定义action#xff0c;我们该如何设计呢#xff1f;
自定义action
1、手写视图逻辑
1.1、先在视图集里自定义action方法#xff0…之前我们的视图类可以继承GenericViewSet或者ModelViewSet我们不用再自定义通用的action方法但是有时候我们需要自定义action我们该如何设计呢
自定义action
1、手写视图逻辑
1.1、先在视图集里自定义action方法名称为names
class ProjectsViewSet(viewsets.ModelViewSet):# 指定当前类视图需要使用的查询集queryset ProjectsModel.objects.all()# 指定当前类视图需要使用的序列化器类serializer_class ProjectModelSerializer# lookup_field Id# 声明需要使用的引擎类filter_backends [filters.SearchFilter,filters.OrderingFilter]# 定义需要过滤的字段search_fields [name, id]# 定义需要排序的字段ordering_fields [id, name]# 声明需要使用的分页引擎pagination_class PageNumberPaginationaction(methods[GET, POST], detailFalse)def names(self, request, *args, **kwargs):qs self.get_queryset()lst []for obj in qs:dict {id: obj.id,name: obj.name,}lst.append(dict)return Response(lst, content_typeapplication/json)
1.2、在路由表url.py中定义新的路由
urlpatterns [path(projects/names/,views.ProjectsViewSet.as_view({get:names,post:names})),
] 支持get和post请求方式 2、使用序列化器类
2.1创建一个新的序列化器类
class ProjectNameSerializer(serializers.ModelSerializer):class Meta:model ProjectsModelfields (id, name)
2.2路由表定义路由
urlpatterns [path(projects/names/,views.ProjectsViewSet.as_view({get:names,post:names})),
] 仅仅只有视图集继承Viewset或者GenericViewset之后才具备方法名与action进行一一对应的功能 2.3 重写视图类中的自定义action方法
from .serializers import ProjectNameSerializeraction(methods[GET, POST], detailFalse)def names(self, request, *args, **kwargs):qs self.get_queryset()# lst []# for obj in qs:# dict {# id: obj.id,# name: obj.name,# }# lst.append(dict)# return Response(lst, content_typeapplication/json)serializer_obj ProjectNameSerializer(instanceqs, manyTrue)return Response(serializer_obj.data, statusstatus.HTTP_200_OK) 2.4 将ProjectNameSerializer抽离出来并且重写get_serializer_class方法 如果当前类视图中使用了多个不同的序列化器类那么可以将get_serializer_class重写继承视图集类之后会提供action属性指定当前请求的action方法名称可以根据不同的action去选择不同的序列化器类不同的查询集 action(methods[GET, POST], detailFalse)def names(self, request, *args, **kwargs):qs self.get_queryset()serializer_objself.get_serializer(instanceqs, manyTrue)return Response(serializer_obj.data, statusstatus.HTTP_200_OK)def get_serializer_class(self):if self.actionnames:return ProjectNameSerializerreturn self.serializer_class 如果请求的是/projects/names/使用的是自定义的序列化器类进行数据输出 如果请求的是其他路由路径能够使用全局指定的序列化器类serializer_classProjectModelSerializer正常处理数据进行序列化输出 可以使用action装饰器指定自定义action方法使用路由器时会自动生成路由条目如果不指定methods那么当前action只支持GET方法请求可以指定当前action支持多个请求方法需要将请求方法大写添加至列表中detail指定当前action是否为详情视图url_path指定url的路径字符串url_name指定url路径的名称如果不指定url_path和url_name默认为action方法名称 注册路由
在路由表中导入routers
from rest_framework import routersrouter routers.SimpleRouter()
# 注册路由
router.register(rprojects, views.ProjectsViewSet)urlpatterns router.urls
注册路由 仅仅只有视图集才支持定义路由器功能register方法可以注册路由条目第一个参数为路由条目的前缀往往需要添加r子应用名第二个参数为视图集对象无需调用as_view({}) 可以定义DefaultRouter对象相比SimpleRouter路由对象会自动添加一个根路由指定当前项目的入口地址 router routers.DefaultRouter() 如果没有指定url_path和url_name则通过路由名称去获取URL路径 如果在action里指定了url_path和url_name则url_path指定url的路径字符串url_name指定url路径的名称
action(methods[GET, POST], detailFalse,url_pathna, url_namean)
def names(self, request, *args, **kwargs):qs self.get_queryset() 有时候有些路由我们不想通过路由器生成需要在urlpatterns里生成
方式一可以附加router.urls到现有视图的列表.
from rest_framework import routersrouter routers.SimpleRouter()
# 注册路由
router.register(rprojects, views.ProjectsViewSet)
urlpatterns []
urlpatterns router.urls方式二或者可以使用 Django 的include函数就像这样
from rest_framework import routersrouter routers.SimpleRouter()
# 注册路由
router.register(rprojects, views.ProjectsViewSet)
urlpatterns [path(, include(router.urls))
]