如何在DRF中无需提供ID即可获取并更新单例模型实例?
如何在DRF中无需提供ID即可获取并更新单例模型实例?
嗨,这个问题我之前也碰到过!单例模型确实不需要带ID,带ID反而显得多余,下面给你几个实用的解决办法:
方法一:改用APIView(最直接简单)
既然我们只需要处理单例的获取和更新,完全可以抛弃ViewSet,直接用APIView来写,这样路由可以直接绑定到/settings路径,不需要任何ID参数。
代码示例:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status class GeneralSettingsAPIView(APIView): def get(self, request): # 直接获取单例实例 settings = GeneralSettings.get_solo() serializer = GeneralSettingsSerializer(settings) return Response(serializer.data) def put(self, request): settings = GeneralSettings.get_solo() serializer = GeneralSettingsSerializer(settings, data=request.data) # 验证数据,不合法直接抛异常 serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_200_OK)
然后路由配置不用router,直接加路径:
from django.urls import path urlpatterns = [ # 其他路由... path("settings/", GeneralSettingsAPIView.as_view(), name="api-settings"), ]
这样访问/api/settings就可以直接GET获取、PUT更新,完全不需要ID,逻辑也更清晰。
方法二:继续使用ViewSet,调整路由映射
如果你想继续保留ViewSet的结构(比如要复用一些通用逻辑),可以手动调整路由,把/settings直接映射到ViewSet的retrieve和update方法,同时保留你已经重写的get_object方法(这个方法写得很对,直接返回单例)。
首先你的ViewSet可以保持不变:
class GeneralSettingsViewSet( RetrieveModelMixin, UpdateModelMixin, GenericViewSet, ): queryset = GeneralSettings.objects.all() serializer_class = GeneralSettingsSerializer http_method_names = ["get", "put"] def get_object(self) -> GeneralSettings: return GeneralSettings.get_solo()
然后不要用router.register,而是手动添加路由:
from django.urls import path urlpatterns = [ # 其他路由... path( "settings/", GeneralSettingsViewSet.as_view({"get": "retrieve", "put": "update"}), name="api-settings" ), ]
这样/settings就会直接触发retrieve(GET)和update(PUT)动作,而因为你重写了get_object,不管有没有传入ID,都会返回单例实例,完美解决问题。
额外小提示
- 你的
queryset可以简化一下,比如写成GeneralSettings.objects.filter(pk=GeneralSettings.get_solo().pk),不过因为你已经重写了get_object,其实这个queryset对retrieve和update方法没有实际影响,只是DRF要求GenericViewSet必须有queryset属性而已。 - 记得把
http_method_names设置成["get", "put"],避免开放不必要的HTTP方法(比如delete,单例模型删了可就麻烦了)。
备注:内容来源于stack exchange,提问作者Ticoincoin
相关产品推荐
相关产品推荐

