Django DRF:限制视图集中的看跌期权
我想限制我的视图集,以便它允许基于权限的不同输入: 我的模型:Django DRF:限制视图集中的看跌期权,django,django-rest-framework,Django,Django Rest Framework,我想限制我的视图集,以便它允许基于权限的不同输入: 我的模型: class Link(models.Model): name = models.CharField("name", max_length = 128) page = models.PositiveIntegerField("page", default = 1, choices = [(1, 1), (2, 2), (3, 3)]) layouts = models.M
class Link(models.Model):
name = models.CharField("name", max_length = 128)
page = models.PositiveIntegerField("page", default = 1, choices = [(1, 1), (2, 2), (3, 3)])
layouts = models.ManyToManyField(Layout)
class Layout(models.Model):
name = models.CharField("name", max_length = 32)
序列化程序:
class LinkSerializer(serializers.ModelSerializer):
test = serializers.SerializerMethodField("get_layouts")
def get_layouts(self): ## this is not displayed?
return "test"
class Meta:
model = Link
fields = ["name", "page", "test"]
例如,我有一个helper类,它提供所有页面
权限。在restframework API中,我现在有一个从第1-3页的下拉列表,但是如果用户没有使用所有页面的权限,我只想显示page 1
以供选择(或者将其设置为不带输入字段的文本字段)。
同样的问题也适用于ManyToMany
字段:如何将布局下拉选项限制为我在管理计划中为该用户选择的选项
现在我手动检查ViewSet
的PUT
方法中的所有内容,并返回一个“用户不允许…->错误请求”
编辑:BC有人问我,现在我做了这样的事情:
class TestViewSet(viewsets.ViewSet):
serializer_class = LinkSerializer
http_method_names = ['get', 'put', 'head']
authentication_classes = [SessionAuthentication,]
permission_classes = [IsAuthenticated,]
def list(self, request):
...
def put(self, request):
## page logic
if "app.all_pages" in request.user.get_user_permissions():
try:
if not 1 < int(request.data["page"]) <= 3:
return Response(data = "page not 2 or 3",
status = status.HTTP_406_NOT_ACCEPTABLE)
except Exception as E:
return Response(data = f"""Error in page selection: {E}""",
status = status.HTTP_400_BAD_REQUEST)
page = int(request.data["page"])
else:
page = 2
## layout logic:
store = Store.objects.get(user = request.user)
allowed_layouts = [l.id for l in store.layouts.all()]
if not int(request.data["layout"]) in allowed_layouts:
return Response(data = f"""layout not allowed for store {store}""",
status = status.HTTP_406_NOT_ACCEPTABLE)
layout = Layout.objects.get(pk = request.data["layout"])
## do something with page 2 and layout ... in DB/another API
类TestViewSet(ViewSet.ViewSet):
serializer_class=LinkSerializer
http_method_names=['get','put','head']
身份验证\u类=[SessionAuthentication,]
权限\u类=[IsAuthenticated,]
def列表(自我、请求):
...
def put(自我,请求):
##页面逻辑
如果request.user.get_user_permissions()中的“app.all_pages”:
尝试:
如果不是1
p.1
DRF中的权限只是两个方法的包装,下面介绍它的工作原理
class PermissionX:
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj)
return True
这是一个权限,具有\u权限
表示(请求。用户
具有访问
当前视图
?)和具有对象权限
说明(请求。用户
有权对对象
执行操作)
obj
是在视图内作用的对象。如果视图适用于用户,则对象将是User
的实例
这与权限\u类一起使用,如下所示
permission_classes = [IsAuthenticated, PermissionX]
p.2
您通常使用user.has\u perm(perm)
而不是user.permissions中的'name'。这是因为权限可以存在于user.groups
中,而不仅仅是user.permissions
p.3
引发的任何异常都应属于DRF中存在的类型PermissionDenied
p.4
在当前应用的permission.py文件夹中提取您的权限
p.5
您的权限不会集成到django管理员界面中。这是因为它没有使用DRF,也没有使用您的端点。它正在使用django提供给它的东西。这是正常的,我们讨论的逻辑将由API本身强制执行,当您创建自定义仪表板时,您还需要将其作为一种UX在前端强制执行。发布与逻辑相关的视图集。将你的助手方法发布到我的解决方案更新了我的问题(这很有效,但我相信这是一个相当次优的解决方案)。首先:感谢你的详细回答。谢谢!但它并没有包含我问题的一个要点:例如,如果一个用户(a)登录并看到了第1-3页的下拉列表,我如何才能让一个用户(B)(不需要查看所有页面的权限)在登录时显示一个只有一个(第1页)条目的菜单?或者我认为所有这些都是错误的,这都是关于“显示所有内容并在拒绝perm时引发异常”?页面本身可能是一个有许可证的模型这就是CMS-s的工作方式是的,到目前为止我就是这样做的。我只是在想,也许最好是“隐藏”用户无论如何都无法访问的字段/选项。是的,最好是为此创建一个动态序列化程序(有文档记录)