Djiango后端开发入门学习之task05--Router功能理解及应用(含@action应用)

  本文根据datawhale开源Djiango后端开发入门( https://github.com/Joe-2002/sweettalk-django4.2 )Task05:路由组件及自定义函数(@action)做的学习笔记

一、学习目标

  Django-rest 是 django web 框架的一个插件,透过Django REST framework( DRF ) 建立 REST API 非常方便快速。这里学习该框架的Router路由配置和测试。

二、Router路由功能及使用

此部分内容参考datawhale开源Djiango后端开发入门以及另一篇博客网址:http://t.csdn.cn/CeD15

1 URL格式

   REST framework提供了两个router:SimpleRouter,DefaultRouter。路由Router形成URL格式如下:
  (1) SimpleRouter

  (2)DefaultRouter

  与SimpleRouter相比,DefaultRouter会多附带一个默认的API视图,返回一个包含所有列表视图的超链接响应数据。

2 配置流程

(1) 创建Router对象
			导包
			from rest_framework import routers
			创建对象,用于生成路由
			router = routers.SimpleRouter()
			或者:router = routers.DefaultRouter()

(2)注册视图集

             # 将视图集注册到路由器上,字符串里的是URL路径的前缀
         	router.register(prefix(路由前缀), viewset(视图集), base_name(路由名称的前缀))           	
         	如:router.register('GoodsCategory', GoodsCategoryViewSet,base_name='goodscategoryok')
         	或者router.register('GoodsCategory', GoodsCategoryViewSet,base_name='goodscategoryok')

(3)路由映射表

         两种方式书写方式:
			                  urlpatterns = […
			                 ]
			 或		   urlpatterns = [
      						url(r'^', include(router.urls))
						]

三、URL映射方式

   在view.py中,有APIView或其子类以及Viewset两类模块抽象,映射方式有一些差别。下面分别描述:

1 ViewSets视图集

   REST框架包括用于处理ViewSets的抽象,允许开发人员只需要在路由器注册相应的视图集就可使Router类自动操作。
   “ @action 装饰器”用于在 ViewSet 中创建自定义动作(custom action),为 ViewSet 提供了更灵活应用且 @action 只在ViewSet视图集中生效。视图集中附加action装饰器可接收两个参数:(1)methods: 声明该action对应的请求方式.(2)detail: True/False声明该action的路径是否是action对应的请求方式。示例如下:

  	view.py
		 class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
		queryset = BookInfo.objects.all()
		serializer_class = BookInfoSerializer
		@action(methods=['get'], detail=False)
				def latest(self, request):
						...
		@action(methods=['put'], detail=True)
			    def read(self, request, pk):
			    ......

2 APIView或其子类

  APIView不是ViewSet的子类,不支持@action,需要单独设置。映射方式包括自动映射或指定映射URL的两种。
  
(1) 根据url请求,Django自动将请求映射到对应的APIView方法上:

    urls.py:
             url(r'^example/$', ExampleView.as_view(), name='example')
  
    view.py:
					class ExampleView(APIView):
					        def get(self, request):
  							      ...
    
				            def post(self, request):
   					        ...

(2)使用URL名称关键字参数来明确指定所调用的方法。如:

  urls.py:
          url(r'^example/get/$', ExampleView.as_view(name='get'), name='example-get')
          url(r'^example/post/$', ExampleView.as_view(name='post'), name='example-post')

  view.py:
        class ExampleView(APIView):
					name= 'get'
				    def get(self, request):
   								 ...
					name = 'post'        
					def post(self, request):
		.						..

四 应用举例

1 任务需求

  将 modelviewset视图集和apiview类实现基于DefaultRouter的路径配置,并实现可视化输出。
  为此,临时制作了两个数据表已合并且存放到数据库中(1)分类表:书籍、电影和音乐。(2)明细表,其中每类对应两条明细。表内容如下:
   (1)分类表

(2)明细表

2 编程思路

  • 设定已经在models.py中创立好数据表并已有数据
  • view.py文件编写,确定映射的名。(功能中尽量用到task03和tank04的功能函数)
  • urls.py文件编写,确定路由生成和映射方式。
  • 运行并实现。

3 代码实现

以下程序代码来自 https://github.com/Joe-2002/sweettalk-django4.2开源资料,并根据实际数据表数据和功能需求做了细微的适当修改

view.py
导包

   		from django.shortcuts import render
   		from rest_framework.response import Response
   		from .models import *
   		from rest_framework.decorators import api_view
   		from django.shortcuts import get_object_or_404
   		from rest_framework.views import APIView
    	from .serializer import *
    	from rest_framework.decorators import action
    	from django.db.models import Q
   		from rest_framework.viewsets import ModelViewSet

#modelviewset

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

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

#apiview

 class GetGoods(APIView):
       def get(self, request):
       			if request.method=='post':
            		data=request.data.get('分类名字')
      			elif request.method=='GET':
            		data = request.query_params.get('分类名字')
    		goods_category = get_object_or_404(GoodsCategory, name=data)
   			 if goods.exists():
        		goods = Goods.objects.filter(category=goods_category)
        		data = Goods.objects.all()
        		serializer = GoodsSerializer(instance=data, many=True)
       			print(serializer.data)
        		return Response({"status": "已存在", "goods_category": data}, status=200)
    else:
        		return Response({"status": "不存在" ,"goods_category": data}, status=404)

urls.py

 from django.contrib import admin
 from django.urls import path
 from apps.sxqapp03.views import *
 from django.urls import include
 from rest_framework import routers

  router = routers.DefaultRouter()  # 创建DefaultRouter对象
   router.register('GoodsCategory', GoodsCategoryViewSet)# 将视图集注册到路由器上
 urlpatterns = [
 		path('admin/', admin.site.urls),
		path('getgoods/', GetGoods.as_view()),
		]
  urlpatterns += router.urls  # 把生成的url 添加到项目的url配置中

4 运行测试

(1)GoodsCategoryViewSet(ModelViewSet)测试
  • 不指定@action函数名
  • 2)指定@action函数名
#### (2)APIView测试   要求: 采用fitler、APIview以及serializer模块将书籍类名称和序列号打印出来

  models.py模块修改

class GetGoods(APIView):
			    def get(self, request):
   					 if request.method=='post':
        					data = request.data.get('分类名字')
    				elif request.method=='GET':
        					data = request.query_params.get('分类名字')
          	        goods = Goods.objects.all()
    				if goods.exists():
                         goods = Goods.objects.filter(category_id='1')  #category_id属于书籍类**加粗样式**
                        serializer = GoodsSerializer(goods, many=True)  # 请确保导入合适的序列化器
                        print(serializer.data)
                        return Response(serializer.data)
                   else:
                        return Response({"status": "不存在" ,"goods_category": data}, status=404)

  运行后,得到的测试结果如下:

  可见,输出结果和预期一致,功能实现。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值