python - Django 休息 : map 'update' to 'list' using CustomRouter

标签 python django django-rest-framework

问题说明:

有一个使用 REST API 的 Django 项目。路由器定义为:

router = routers.DefaultRouter()

帐户路由器:

router.register('accounts', AccountViewSet)
accounts_router = NestedSimpleRouter(router, r'accounts')

accounts_router 下还有其他路由器使用标准范例(如 Django Reference 中所述),例如:

URL pattern: ^accounts/$ Name: 'account-list'
URL pattern: ^accounts/{pk}/$ Name: 'account-detail'

问题:

现在有一个只有 1 个实例的对象 - singleton_foo。将其详细信息 View 显示为 /accounts/foo_acc/singleton_foo/1 将是一个坏主意,因为用户可能期望 #2、#3 等。

目标:

我想使用自定义路由器将“/accounts/foo_acc/singleton_foo/1”映射到“/accounts/foo_acc/singleton_foo”。基本上,我想在 ListView (list) 中显示和更新 singleton_foo 详细信息 (update)

我试过使用类似的东西:

class SingletonNestedRouter(NestedSimpleRouter):
    routes = [
        Route(
            url=r'^{prefix}/$',
            mapping={'get': 'list'},
            name='{basename}-list',
            initkwargs={'suffix': 'List'}
        ),
        Route(
            url=r'^{prefix}/{pk}/$',
            mapping={'put': 'retrieve'},
            name='{basename}-retrieve',
            initkwargs={'suffix': 'Retrieve'}
        ),
    ]

并将路由器附加到帐户:

accounts_router.register('singleton_foo', SingletonFooViewSet, 'singletonfoo')
ConfigNestedRouter(domains_router, singleton_foo', lookup='singleton_foo')

有什么建议吗?

最佳答案

如果这在您的项目中可行,您可以通过重写 View 集的一些方法来实现相同的行为。这里的核心内容:

  • 仅获取查询集中的第一项(在 get_queryset 中使用“[:1]”),
  • 如果一个新项目已经存在(在 create() 中),则拒绝创建新项目,
  • 重写 get_object() 方法,这样当我们没有为 lookup_field 传递值时它就不会引发异常。

views.py

class SingletonView(viewsets.ModelViewSet):

    serializer_class = SingletonSerializer

    def get_queryset(self):
        return SingletonModel.objects.all()[:1]

    def create(self, request, *args, **kwargs):
        if not self.get_queryset().exists():
            return super(SingletonView, self).create(request, *args, **kwargs)
        else:
            return Response({
                'message': 'Already exists and can be only one!'
            }, status=status.HTTP_400_BAD_REQUEST)

    def get_object(self):
        queryset = self.filter_queryset(self.get_queryset())
        obj = shortcuts.get_object_or_404(queryset)

        # May raise a permission denied
        self.check_object_permissions(self.request, obj)

        return obj

urls.py

urlpatterns = [
    url(r'^$', SingletonView.as_view({'get':'list', 'post': 'create', 'delete': 'destroy', 'put': 'update'})),
]

现在您可以通过相同的 url 访问所有方法(GET、PUT、POST、DELETE),无需 pk 和“仅一个项目”控制。

关于python - Django 休息 : map 'update' to 'list' using CustomRouter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41346321/

相关文章:

python - sqlalchemy线程消息系统

python - 如何判断另一个类中的函数何时被调用

python - 我应该使用高级 GeoDjango 库进行一项简单的计算吗?

python - Django:Django-Rest-Framework 给出归因错误(分页)

django - 在 Django REST framework 中对 ModelViewSet 中的不同操作使用不同的身份验证

python - 外键关系中 drf 序列化器的最佳实践是什么

python - 为什么 TravisCI 找不到我的许可证文件?

python - 从文件 python 中提取 id 和相应的标记并附加到字典中

python, json.loads 期望属性名称 : line 1 column 2 (char 2)

python - Django模型表单: Exclude a field which is not in Model