如何使用DRF编写访问URL时自动递增模型字段的API视图
DRF实现字段自动递增接口解决方案
原有代码问题分析
- 未校验ID对应的记录是否存在:
filter().update()返回受影响的行数,若ID不存在返回值为0,你未对该值做判断,直接执行后续错误的序列化逻辑 - 序列化逻辑完全错误:你将全表
Url_data对象传入序列化器,而非目标单条记录,且更新操作不需要额外校验请求参数再调用save(),属于多余逻辑 - 状态码使用错误:更新操作成功应返回200,而非创建场景的201
基于函数的API View实现
首先导入依赖:
from django.shortcuts import get_object_or_404 from django.db.models import F from rest_framework.decorators import api_view, permission_classes from rest_framework import permissions, status from rest_framework.response import Response from .models import User from .serializers import UserSerializer # 需提前定义对应User模型的序列化器
视图代码:
@api_view(['POST']) @permission_classes([permissions.IsAuthenticatedOrReadOnly]) def increment_user_error(request, user_id): # 找不到记录直接返回404,阻断错误逻辑 user = get_object_or_404(User, id=user_id) # F表达式实现原子递增,避免并发更新冲突 User.objects.filter(id=user_id).update(error=F('error') + 1) # 刷新对象获取更新后的最新值 user.refresh_from_db() serializer = UserSerializer(user) return Response(serializer.data, status=status.HTTP_200_OK)
对应的URL配置(urls.py):
from django.urls import path from .views import increment_user_error urlpatterns = [ path('users/error/<int:user_id>/', increment_user_error, name='increment-error'), ]
基于类的API View实现
from django.shortcuts import get_object_or_404 from django.db.models import F from rest_framework.views import APIView from rest_framework import permissions, status from rest_framework.response import Response from .models import User from .serializers import UserSerializer class IncrementUserErrorView(APIView): permission_classes = [permissions.IsAuthenticatedOrReadOnly] def post(self, request, user_id): user = get_object_or_404(User, id=user_id) User.objects.filter(id=user_id).update(error=F('error') + 1) user.refresh_from_db() serializer = UserSerializer(user) return Response(serializer.data, status=status.HTTP_200_OK)
对应的URL配置:
from django.urls import path from .views import IncrementUserErrorView urlpatterns = [ path('users/error/<int:user_id>/', IncrementUserErrorView.as_view(), name='increment-error'), ]
你原有updateClick视图的修复版本
修复后传入不存在的ID时会直接返回404,不会出现返回201的问题:
@api_view(['POST']) @permission_classes([permissions.IsAuthenticatedOrReadOnly]) def updateClick(request, uri_id): url_obj = get_object_or_404(Url_data, uri_id=uri_id) Url_data.objects.filter(uri_id=uri_id).update(clicks=F('clicks')+1) url_obj.refresh_from_db() serializer = ClickSerializer(url_obj) return Response(serializer.data, status=status.HTTP_200_OK)
内容的提问来源于stack exchange,提问作者Strike
相关产品推荐
相关产品推荐

