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
实例,并应用所有过滤。如果您正在手动执行更新(定义一些自定义操作),您应该