Django 如何限制经过身份验证的用户代表其他人发布?
如果我以Django 如何限制经过身份验证的用户代表其他人发布?,django,django-models,django-rest-framework,Django,Django Models,Django Rest Framework,如果我以user1身份登录,并访问名为RecipeSubmissionViewSet的ViewSet,则POST会获取用户想要提交的配方的recipe\u id。假设recipe模型上有一个owner字段,并且我可以将其与request.user进行比较,如何确保user1不提交user2的配方?我应该为此使用权限类还是有更好的方法?我是从后端的角度讲的,没有考虑到前端当然会过滤掉属于用户的配方,只显示他们自己的配方。您使用的是django认证系统吗?然后您应该能够访问视图中的request.u
user1
身份登录,并访问名为RecipeSubmissionViewSet
的ViewSet
,则POST
会获取用户想要提交的配方的recipe\u id
。假设recipe
模型上有一个owner
字段,并且我可以将其与request.user进行比较,如何确保user1
不提交user2
的配方?我应该为此使用权限类还是有更好的方法?我是从后端的角度讲的,没有考虑到前端当然会过滤掉属于用户的配方,只显示他们自己的配方。您使用的是django认证系统吗?然后您应该能够访问视图中的request.user
,并相应地设置owner
字段
编辑:我想我误解了这个问题
但是可能会有帮助,Nafees Anwar看起来不错。您使用的是django认证系统吗?然后您应该能够访问视图中的
request.user
,并相应地设置owner
字段
编辑:我想我误解了这个问题
但这可能会有所帮助,纳菲斯·安瓦尔看起来不错。有两种方法。您可以筛选出queryset或定义权限类
如果您像这样重写
get\u queryset
方法
class RecipeSubmissionViewSet(...):
def get_queryset(self):
return Recipe.objects.filter(owner=self.request.user)
# you can also use filtration based on action name like this
# if self.action == 'update':
# return Recipe.objects.filter(owner=self.request.user)
# return Recipe.objects.all()
from rest_framework.permissions import BasePermission
class RecipeSubmissionPermission(BasePermission):
def has_object_permission(self, request, view, obj):
# you can also check permission here based on action
# if view.action == 'update':
# pass
return request.user.is_authenticated and obj.owner == request.user
class RecipeSubmissionViewSet(...):
permission_classes=[RecipeSubmissionPermission]
用户将得到404响应,并且将永远无法访问他拥有的对象以外的对象
第二个选择是权限类。您可以像这样定义自定义权限类并显式检查所有权
class RecipeSubmissionViewSet(...):
def get_queryset(self):
return Recipe.objects.filter(owner=self.request.user)
# you can also use filtration based on action name like this
# if self.action == 'update':
# return Recipe.objects.filter(owner=self.request.user)
# return Recipe.objects.all()
from rest_framework.permissions import BasePermission
class RecipeSubmissionPermission(BasePermission):
def has_object_permission(self, request, view, obj):
# you can also check permission here based on action
# if view.action == 'update':
# pass
return request.user.is_authenticated and obj.owner == request.user
class RecipeSubmissionViewSet(...):
permission_classes=[RecipeSubmissionPermission]
在这种情况下,用户将获得403权限错误
如果您同时使用这两种方法404将是首选
你可以使用任何你想要的方法,或者两者都可以。Permission类看起来更具编程性和结构化,但用户将知道具有此id的对象存在,但他没有更新它的权限。但若覆盖queryset,用户甚至无法知道对象是否存在,从而更安全。有两种方法。您可以筛选出queryset或定义权限类
如果您像这样重写
get\u queryset
方法
class RecipeSubmissionViewSet(...):
def get_queryset(self):
return Recipe.objects.filter(owner=self.request.user)
# you can also use filtration based on action name like this
# if self.action == 'update':
# return Recipe.objects.filter(owner=self.request.user)
# return Recipe.objects.all()
from rest_framework.permissions import BasePermission
class RecipeSubmissionPermission(BasePermission):
def has_object_permission(self, request, view, obj):
# you can also check permission here based on action
# if view.action == 'update':
# pass
return request.user.is_authenticated and obj.owner == request.user
class RecipeSubmissionViewSet(...):
permission_classes=[RecipeSubmissionPermission]
用户将得到404响应,并且将永远无法访问他拥有的对象以外的对象
第二个选择是权限类。您可以像这样定义自定义权限类并显式检查所有权
class RecipeSubmissionViewSet(...):
def get_queryset(self):
return Recipe.objects.filter(owner=self.request.user)
# you can also use filtration based on action name like this
# if self.action == 'update':
# return Recipe.objects.filter(owner=self.request.user)
# return Recipe.objects.all()
from rest_framework.permissions import BasePermission
class RecipeSubmissionPermission(BasePermission):
def has_object_permission(self, request, view, obj):
# you can also check permission here based on action
# if view.action == 'update':
# pass
return request.user.is_authenticated and obj.owner == request.user
class RecipeSubmissionViewSet(...):
permission_classes=[RecipeSubmissionPermission]
在这种情况下,用户将获得403权限错误
如果您同时使用这两种方法404将是首选
你可以使用任何你想要的方法,或者两者都可以。Permission类看起来更具编程性和结构化,但用户将知道具有此id的对象存在,但他没有更新它的权限。但如果您重写queryset,用户甚至无法知道对象是否存在,从而更安全。Nafees的答案几乎就是正确的 我一直在开发面向用户的多租户微服务,其规则(根据我的项目规范)如下:
- 用户不能代表其他公司/用户创建项目
- 用户无法查看/编辑属于其他公司的项目
def get_queryset(self):
return self.queryset.filter(user=request.user)
为了禁止编辑其他人的内容,这是在序列化程序上完成的
class SomeSerializer(...):
def validate(self, data):
data.pop('user', None)
data['user'] = self.context['request'].user
根据上述内容,如果user1请求user2信息,则视图集中的get_queryset
将始终返回404
validate
功能将阻止分配。也就是说,如果user1创建了分配给user2的内容,它将更倾向于分配user1,这种行为是我在应用程序中需要的,你可以总是引发序列化程序。ValidationError(“你不能将内容分配给user2”)
,如果这是你需要的,而不是像我在用例中那样重新分配用户。在validate
中使用此逻辑,可以确保任何可写函数都将始终具有与该序列化程序相同的行为
希望这能有所帮助。Nafees的答案差不多是正确的 我一直在开发面向用户的多租户微服务,其规则(根据我的项目规范)如下:
- 用户不能代表其他公司/用户创建项目
- 用户无法查看/编辑属于其他公司的项目
def get_queryset(self):
return self.queryset.filter(user=request.user)
为了禁止编辑其他人的内容,这是在序列化程序上完成的
class SomeSerializer(...):
def validate(self, data):
data.pop('user', None)
data['user'] = self.context['request'].user
根据上述内容,如果user1请求user2信息,则视图集中的get_queryset
将始终返回404
validate
功能将阻止分配。也就是说,如果user1创建了分配给user2的内容,它将更倾向于分配user1,这种行为是我在应用程序中需要的,你可以总是引发序列化程序。ValidationError(“你不能将内容分配给user2”)
,如果这是你需要的,而不是像我在用例中那样重新分配用户。在validate
中使用此逻辑,可以确保任何可写函数都将始终具有与该序列化程序相同的行为
希望这能有所帮助。谢谢你的回答。我实际上是在使用
get\u queryset
的方式,但是在帖子上呢?限制一个用户发布另一个用户的配方怎么样?我现在是否使用权限类,或者我是否可以在POST
中以某种方式利用get\u queryset
?当用户在更新配方时get\u queryset
将自动用于获取recipe
实例,并应用所有过滤。如果您正在手动执行更新(定义一些自定义操作),您应该