我有3个对象 - Company,Expert和RecentProject,其中RecentProject具有ForeignKey to Company和ManyToMany与专家的关系:
class RecentProject(BaseProfileObject):
company = models.ForeignKey(
'experts.Company',
verbose_name=_("Company"),
blank=True,
null=True,
related_name='projects')
experts = models.ManyToManyField(
"Expert",
verbose_name=_("Experts"),
blank=True,
null=True,
related_name='projects')
class Meta:
verbose_name = _("Recent project")
verbose_name_plural = _("Recent projects")
我想要的是能够从端点发布新的近期项目,如
api / v1 / companies / 1 / recentprojects /和api / v1 / experts / 1 / recentprojects /
在第一种情况下,如果用户可以对公司进行更改,则seralizer应该能够验证(或者更确切地进行权限检查),如果用户可以对专家进行更改,则可以进行第二种情况。 我似乎无法找到的是如何让权限知道父对象的例子(第一种情况下的公司和第二种情况下的专家)。
我知道可以使用权限来完成,所以我创建了以下权限:
class UserCanModifyCompany(permissions.BasePermission):
def has_permission(self, request, view):
# Do check here
return False
我将它添加到我的视图中: class RecentProjectViewSet(viewsets.ModelViewSet): queryset = RecentProject.objects.all() serializer_class = RecentProjectSerializer
@permission_classes((UserIsAuthenticatedExpert, UserCanModifyCompany))
def create(self, request, *args, **kwargs):
return super(RecentProjectViewSet, self).create(request, *args, **kwargs)
@permission_classes((UserIsAuthenticatedExpert, UserCanModifyCompany))
def update(self, request, *args, **kwargs):
return super(RecentProjectViewSet, self).update(request, *args, **kwargs)
但是我怎样才能确保权限检查有可用于公司/专家访问检查的信息。或者我是否需要为公司/专家最近的项目保存创建不同的视图集,并为这两个项目设置不同的权限类别?
答案 0 :(得分:2)
首先,为同一资源创建两个不同的端点并不是一个好主意。我建议你使用单一端点:api/v1/recentprojects/
。
话虽如此,我一直处于类似情况,我认为您最好的选择是在 公司和专家视图集 上使用@detail_route
。
例如,在ExpertViewSet
:
@detail_route(methods=['post'], , permission_classes=[UserIsAuthenticatedExpert, UserCanModifyCompany])
def recentprojects(self, request, pk=None):
expert = self.get_object()
serializer = RecentProjectSerializer(data=request.data)
if serializer.is_valid():
recent_project = serializer.save(company=somecompany)
recent_project.experts.add(expert)
return Response({'status': 'ok'})
else:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
这样您就可以将新的最新项目发布到api/v1/experts/{pk}/recentprojects/
。
至于权限,您需要实现has_object_permission
,因为这是一个单一的对象端点:
class UserIsAuthenticatedExpert(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return some_condition
您还可以与get_queryset
一起覆盖self.action
以过滤端点可以操作的专家或公司实例,但这会引发404错误而不是403错误。