Django-DRF(路由组件)和自定义函数
Django-DRF路由简介:
DRF主要提供了SimpleRouter和DefaultRouter两种路由。
DefaultRouter
是Django REST framework中提供的一个路由器类,用于自动生成URL路由。
路由器是将URL与视图函数或视图集关联起来的一种机制。Django REST framework的路由器通过简单的配置可以自动生成标准的URL路由,从而减少了手动编写URL路由的工作量。
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()),
]
print(router.urls)
# 添加到urlpatterns中,相当于在urlpatterns中添加path
urlpatterns += router.urls
views.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 .serializers import *
from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet
# 面向对象编程
class GetGoods(APIView):
def get(self, request):
data = Goods.objects.all()
serializer = GoodsSerializer(instance=data, many=True)
print(serializer.data)
return Response(serializer.data)
def post(self, request):
# 从请求数据中提取字段
request_data = {
"category": request.data.get("Goodscategory"),
"number": request.data.get("number"),
"name": request.data.get("name"),
"barcode": request.data.get("barcode"),
"spec": request.data.get("spec"),
"shelf_life_days": request.data.get("shelf_life_days"),
"purchase_price": request.data.get("purchase_price"),
"retail_price": request.data.get("retail_price"),
"remark": request.data.get("remark"),
}
# 使用 create() 方法创建新的商品对象
new_goods = Goods.objects.create(**request_data)
# 对创建的对象进行序列化,并作为响应返回
serializer = GoodsSerializer(instance=new_goods)
return Response(serializer.data)
# modelviewset
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 你调用了自定义的函数")
class FilterGoodsCategoryAPI(APIView):
# request 表示当前的请求对象
# self 表示当前实例对象
def get(self, request, format=None):
print(request.method)
return Response('ok')
def post(self, request, format=None):
print(request.method)
return Response('ok')
def put(self, request, format=None):
print(request.method)
return Response('ok')
# 函数式编程
@api_view(['POST', 'GET'])
def FilterGoodsCategory(request):
data = request.data['分类名字']
goods_category = get_object_or_404(GoodsCategory, name=data)
print(goods_category)
ans = Goods.objects.filter(category=goods_category).all().values()
print(ans)
print("object type:", type(Goods.objects))
print("object.all() type:", type(Goods.objects.all()))
print("object.all().values type:", type(Goods.objects.all().values()))
print("object.get(id=1) type:", type(Goods.objects.get(id=1)))
return Response(ans)
# 函数式编程
@api_view(['POST', 'GET'])
def InsertGoodsCategory(request):
category_name = request.data.get('分类名字')
# 获取分类对象或创建新的分类对象
category, created = GoodsCategory.objects.get_or_create(name=category_name)
# 判断是否已存在分类
if not created:
return Response({"status": "已存在", "goods_category": category_name}, status=200)
else:
return Response({"message": f"Successfully inserted category '{category_name}'."})
Django-DRF 自定义函数
action装饰器
Django默认的路由分发规则决定了视图函数只能以get、post等请求方式命名,如果想要使用自定义的方式命名,我们可以使用action去映射请求方法名与自定义方法,@action
是 Django REST framework 中的一个装饰器,用于将自定义函数转换为视图集的一个动作。@action
装饰器提供了一种定义自定义函数的方式,这些函数并不直接对应于标准的 CRUD 操作(Create-Read-Update-Delete),而是实现一些其他的自定义行为或业务逻辑。
比如APIView的这段代码:
# 面向对象编程
class FilterGoodsCategoryAPI(APIView):
# request 表示当前的请求对象
# self 表示当前实例对象
def get(self, request, format=None):
print(request.method)
return Response('ok')
def post(self, request, format=None):
print(request.method)
return Response('ok')
def put(self, request, format=None):
print(request.method)
return Response('ok')
使用步骤:
- 导入包:
from rest_framework.decorators import action
-
在视图集类中,使用 @action 装饰器来定义一个自定义函数,指定 detail 参数为 True 或 False,表示该函数是针对单个对象还是整个集合的操作。
-
在自定义函数中,编写你的业务逻辑,返回一个 Response 对象,包含你想要返回的数据和状态码。
-
在自定义函数中,编写你的业务逻辑,返回一个 Response 对象,包含你想要返回的数据和状态码。
-
在浏览器或客户端中,访问你的自定义函数对应的 URL,传递必要的参数,获取返回的数据。
示例
# views.py
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from django.contrib.auth.models import User
from .serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
@action(detail=False, methods=['get'])
def search(self, request):
# 获取查询参数
username = request.query_params.get('username', None)
# 判断参数是否存在
if username is not None:
# 根据参数查询用户对象
user = User.objects.filter(username=username).first()
# 判断用户对象是否存在
if user is not None:
# 序列化用户对象
serializer = self.get_serializer(user)
# 返回序列化后的数据和状态码
return Response(serializer.data, status=200)
else:
# 返回错误信息和状态码
return Response({'error': 'User not found'}, status=404)
else:
# 返回错误信息和状态码
return Response({'error': 'Username parameter is required'}, status=400)
# urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import UserViewSet
# 创建路由器对象
router = DefaultRouter()
# 注册视图集,并指定 basename 参数
router.register('users', UserViewSet, basename='user')
# 定义 URL 路由
urlpatterns = [
path('', include(router.urls)),
]
课程总结以及自身一些之前不太了解的知识点
Django类视图(CBV)
FBV(function base views) 基于函数的视图,就是在视图里使用函数处理请求。
CBV(class base views) 基于类的视图,就是在视图里使用类处理请求。
在前面,已经使用了FBV视图,在定义函数阶段,只要定义参数request,并且绑定响应的路由,就可以做到视图与路由的绑定
但是函数视图对于复杂项目,用起来更加繁琐,无法实现更加方便的面向对象,并且可以配合Django实现Mixin类型。
而CBV视图,在大规模项目中,用起来更加方便简单。
类视图与函数视图不一样,需要实现以下几种定义
- 函数中为不同的HTTP请求方法单独定义函数,例如接受POST请求,就需要类中定义post函数,以此类推,即接受什么请求就定义什么函数
- 类视图必须继承自 django.views.View 父类
- 类视图的请求入口,通过类中的as_view()静态方法实现->View 父类 已经定义
总结:
经过8天左右的入门学习我大致了解了Django的一些基础操作及命令,但是还有一些具体的点还是有些不太熟悉,还需要加强了解学习,比如:Django-DRF框架的一些方式方法作用、含义等的了解,QuerySet和Instance的使用等。