问题说明:
有一个使用 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/