Django后端开发入门 之 ModelViewSet和自定义函数

摘要:本文是基于项目文档来完成task5和task6的任务。上一个task我们学习了如何使用APIView来实现不同的接口,这次任务我们将学习Django中的一个新概念-ModelViewSet,ModelViewSet最大的优势是支持自定义函数,大大提高了代码可读性和自由度。为了将新建的方法引入到urls,我们还需要学习路由的概念,通过这种方式,就可以掌握如何在Django中便捷地对数据表进行增删改查了。

ModelViewSet

概念:是 Django REST framework 提供的一个视图集类,它封装了常见的模型操作方法,包括默认的增删改查功能。也就是使用 ModelViewSet 后,你将自动获得默认的 CRUD 方法。

使用:
我们只需要在view.py中将代码新增如下:

# modelviewset
class GoodsCategoryViewSet(ModelViewSet):
    queryset = GoodsCategory.objects.all()

    @action(detail=False, methods=['get'])
    def latest(self, request):
        latest_obj = GoodsCategory.objects.latest('id') # 获取最大id对应的对象
        serializer = GoodsCategorySerilizer(instance=latest_obj)
        return Response(serializer.data)
    
    @action(detail=False, methods=['get','post'])
    def delete_example(self, request):
        try:
            name = request.data.get('name', '')
            categories_to_delete = GoodsCategory.objects.filter(name=name)
            deleted_count = categories_to_delete.delete()
            print(f"Deleted {deleted_count} categories.")
            return Response({"status": "success" ,"category": name}, status=200)
        except Exception as e:
            return Response({"message": f"Failed for del with error: {e}"}, status=404)

    @action(detail=False, methods=['get','post'])
    def create_example(self, request):
        name = request.data.get('name')
        remark = request.data.get('remark', '无')
        category, created = GoodsCategory.objects.create(name=name, remark=remark)
        print(category, created)
        if not created:
            return Response({"status": "已存在", "category": name}, status=200)
        else:
            return Response({"message": f"Successfully create category '{name}'."})

class GoodsViewSet(ModelViewSet):
    queryset = Goods.objects.all()

    @action(detail=False, methods=['get'])
    def latest(self, request):
        latest_obj = Goods.objects.latest('id') # 获取最大id对应的对象
        serializer = GoodsSerializer(instance=latest_obj)
        return Response(serializer.data)
    
    @action(detail=False, methods=['get','post'])
    def delete_example(self, request):
        try:
            name = request.data.get('name', '')
            goods_to_delete = Goods.objects.filter(name=name)
            deleted_count = goods_to_delete.delete()
            print(f"Deleted {deleted_count} goods.")
            return Response({"status": "success" ,"goods": name}, status=200)
        except Exception as e:
            return Response({"message": f"Failed for del with error: {e}"}, status=404)

    @action(detail=False, methods=['get','post'])
    def create_example(self, request):
        cate_name = request.data.get("Goodscategory")
        category_ins = GoodsCategory.objects.get(name=cate_name)
        if not category_ins:
            category_ins = GoodsCategory(name=cate_name)
            category_ins.save()
        request_data = {
            "category": category_ins,
            "number": request.data.get("number", 1),
            "name": request.data.get("name"),
            "barcode": request.data.get("barcode", 1),
            "spec": request.data.get("spec", 'high'),
            "shelf_life_days": request.data.get("shelf_life_days", 5),
            "purchase_price": request.data.get("purchase_price", 5),
            "retail_price": request.data.get("retail_price", 5),
            "remark": request.data.get("remark", '无'),
        }
        try:
            new_goods = Goods.objects.create(**request_data)
            serializer = GoodsSerializer(instance=new_goods)
            return Response(serializer.data)
        except Exception as e:
            return Response({"message": f"Failed with {e}"}, status=404)

自定义函数

上述代码中的@action的DRF中一个装饰器,用于在 ViewSet 中创建自定义动作(custom action),为 ViewSet 提供了更灵活应用且 @action 只在ViewSet视图集中生效。视图集中附加action装饰器可接收两个参数:

  • methods: 声明该action对应的请求方式.
  • detail: detail=False表示该动作不需要处理单个对象,而是处理整个集合;

路由组件

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

用法:
在urls.py引入from rest_framework import routers,然后将view.py中新增的两个ModelViewSet注册进来:

router = routers.DefaultRouter()
router.register('Goods', GoodsViewSet)
router.register('GoodsCate', GoodsCategoryViewSet)
urlpatterns = [
    path('admin/', admin.site.urls),
    path('insertgoodscategory/', InsertGoodsCategory),
    path('filtergoodscategory/', FilterGoodsCategory),
    path('delgoodscategory/', DelGoodsCategory),
    path('addgoods/', AddGoods),
    path('goodscateapi/', GoodsCategoryAPI.as_view()),
    path('goodsapi/', GoodsAPI.as_view()),
]
urlpatterns += router.urls

接口测试

定义了上述自定义函数,并经过路由后,打开postman进行接口测试,注意在ViewSet后面需要接上自定义的方法名,如下:

http://127.0.0.1:8000/GoodsCate/latest/
http://127.0.0.1:8000/GoodsCate/create_example/
http://127.0.0.1:8000/GoodsCate/delete_example/
http://127.0.0.1:8000/Goods/latest/
http://127.0.0.1:8000/Goods/create_example/
http://127.0.0.1:8000/Goods/delete_example/

可能遇到下面报错:

You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to 127.0.0.1:8000/goodsapi/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings. 

这个错误提示是由Django的APPEND_SLASH设置引起的。APPEND_SLASH设置为True时,Django会自动在URL末尾添加斜杠(‘/’),以确保URL一致性。但是,当使用POST请求访问不以斜杠结尾的URL时,Django无法在重定向时保持POST数据的完整性,因此会出现该错误。

所以以上url最后要加上’/',这样,请求会直接匹配到以斜杠结尾的URL规则,而不会触发重定向。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 PyCharm 中使用 Django 进行后端接口开发,可以按照以下步骤进行: 1. 创建 Django 项目 在 PyCharm 中创建 Django 项目,可以通过菜单栏中的 File -> New Project -> Django Project 来完成。在弹出的窗口中,输入项目名称和位置,点击 Create 按钮即可创建 Django 项目。 2. 创建 Django 应用 在 Django 项目中,可以创建多个应用,每个应用可以包含多个视图函数和模型类。在 PyCharm 中,可以通过右键点击项目名称,选择 New -> Django App 来创建应用。在弹出的窗口中,输入应用名称和位置,点击 Create 按钮即可创建 Django 应用。 3. 编写视图函数 在 Django 应用中,可以定义多个视图函数来处理不同的请求。在 PyCharm 中,可以在应用的 views.py 文件中编写视图函数。例如,可以定义一个处理 GET 请求的视图函数: ``` from django.http import HttpResponse def hello(request): return HttpResponse("Hello, world!") ``` 4. 配置 URL 映射 在 Django 中,URL 映射可以将请求的 URL 映射到对应的视图函数。在 PyCharm 中,可以在应用的 urls.py 文件中配置 URL 映射。例如,可以配置一个将根路径映射到 hello 视图函数的 URL 映射: ``` from django.urls import path from . import views urlpatterns = [ path('', views.hello, name='hello'), ] ``` 5. 运行 Django 项目 在 PyCharm 中,可以通过菜单栏中的 Run -> Run 'manage.py' 来运行 Django 项目。在运行之后,可以在浏览器中访问 http://127.0.0.1:8000/ 来测试 hello 视图函数的效果。 以上就是使用 PyCharm 和 Django 进行后端接口开发的基本步骤。当然,在实际开发中,还需要学习更多的 Django 相关知识和技能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值