说我有一个简单的应用程序,用户,组和用户都是组的成员(M2M关系)。因此,我创建了一个视图集,该视图集应执行以下操作:
GET /group
列出所有组GET /group/1
提供了组的详细信息POST /group/1/member
将请求中指定的成员添加到组1 GET /group/1/member
列出第1组的所有成员为了使代码尽可能可读,我想出了以下解决方案:
class GroupViewSet(ModelViewSet):
...
@action(detail=True, methods=["get", "post"])
def member(self, request, *args, **kwargs):
return MembershipView.as_view()(request, *args, **kwargs)
class MembershipView(ListCreateAPIView):
# handle the membership somehow here
但是,这种方法以
结尾The `request` argument must be an instance of `django.http.HttpRequest`, not `rest_framework.request.Request`.
尽管手动实例化另一个视图中的视图并传递请求最有可能在纯Django中工作,但是REST框架拒绝执行此操作,因为每个DRF视图都希望有一个纯Django请求,而不能仅接受现有的DRF请求是。
我有两个问题:
答案 0 :(得分:0)
首先,我认为您的URL结构可能不是真正的RESTful。您应该使用复数形式访问资源,即
POST /groups/
返回组。
POST /groups/1
从组列表中获取ID为1的项目。这使事情更清晰了。
其次,我个人会重新设计流程,因为我认为当前的设计会使REST结构过于复杂。
成员和组有不同的资源吗?我会说是的,这些是截然不同的。因此,应将它们保留在不同的端点中。具有/ members /和/ groups /,并使用django内置的过滤器来获得所需的行为,即:
GET /members/?group_id=1
这更干净,更RESTful。您要获取的group_id为1的成员。
如果您确实想保留此嵌入式结构,则可以对rest_framework.decorators
list_route
和detail_route
进行一些魔术操作,以实现当前所需的行为。
但是,根据我的经验,我发现像这样的嵌入会导致某些django机制出现问题,并使URL路由有些粗糙。我真的建议保留不同的药物。
您基本上是在这样做:
/list-view/detail-view/list-view/
我可以理解这种设计在纸上有意义的用例,但我认为这不是理想的选择。