Django 对象级权限

Django 对象级权限,django,django-rest-framework,Django,Django Rest Framework,我想知道对象级权限的正确位置。我正在使用django guardian与post_save hook进行此操作: def post_save(self, obj, created=False): assign_perm('view_media', self.request.user, obj) assign_perm('delete_media', self.request.user, obj) 这对于简单对象很好,但是对于链接对象会有问题。让我们举一个例子: 型号 class

我想知道对象级权限的正确位置。我正在使用django guardian与post_save hook进行此操作:

def post_save(self, obj, created=False):
    assign_perm('view_media', self.request.user, obj)
    assign_perm('delete_media', self.request.user, obj)
这对于简单对象很好,但是对于链接对象会有问题。让我们举一个例子:

型号

class FirstModel(models.Model):
    id = models.AutoField(primary_key=True, name='id', db_column='id')
    name = models.CharField(max_length=255, blank=True, null=True)

    class Meta:
        app_label = 'choices'

        permissions = (
            ('view_firstmodel', 'Can view firstmodel'),
            ('update_firstmodel', 'Can update firstmodel')
        )


class SecondModel(models.Model):
    id = models.AutoField(primary_key=True, name='id', db_column='id')
    name = models.CharField(max_length=255, blank=True, null=True)
    parent_firstmodel = models.ForeignKey(FirstModel, related_name='secondmodel_objects')

    class Meta:
        app_label = 'choices'

        permissions = (
            ('view_secondmodel', 'Can view secondmodel'),
            ('update_secondmodel', 'Can update secondmodel')
        )
class SecondModelSerializer(serializers.ModelSerializer):

    parent_firstmodel = serializers.PrimaryKeyRelatedField()

    class Meta:
        model = SecondModel
        fields = ('id', 'name', 'parent_firstmodel')


class FirstModelSerializer(serializers.ModelSerializer):

    secondmodel_objects = SecondModelSerializer(many=True, allow_add_remove=True)

    class Meta:
        model = FirstModel
        fields = ('id', 'name', 'secondmodel_objects')
class FirstModelList(ListCreateAPIView):
    serializer_class = FirstModelSerializer
    model = FirstModel

    def post_save(self, obj, created=False):
        assign_perm('view_firstmodel', self.request.user, obj)
        assign_perm('update_firstmodel', self.request.user, obj)
        assign_perm('delete_firstmodel', self.request.user, obj)

    def get_queryset(self):
        return get_objects_for_user(self.request.user, 'view_firstmodel', klass=FirstModel)

class FirstModelDetail(RetrieveDestroyAPIView):
    serializer_class = FirstModelSerializer
    model = FirstModel

    def get_queryset(self):

        if self.request.method == 'GET':
            required_permission = 'view_firstmodel'
        elif self.request.method == 'PATCH':
            required_permission = 'update_firstmodel'
        elif self.request.method == 'DELETE':
            required_permission = 'delete_firstmodel'

        return get_objects_for_user(self.request.user, required_permission, klass=FirstModel)

class SecondModelList(ListCreateAPIView):
    serializer_class = SecondModelSerializer
    model = SecondModel

    def post_save(self, obj, created=False):
        assign_perm('view_secondmodel', self.request.user, obj)
        assign_perm('update_secondmodel', self.request.user, obj)
        assign_perm('delete_secondmodel', self.request.user, obj)

    def get_queryset(self):
        return get_objects_for_user(self.request.user, 'view_secondmodel', klass=SecondModel)


class SecondModelDetail(RetrieveDestroyAPIView):
    serializer_class = SecondModelSerializer
    model = SecondModel

    def get_queryset(self):

        if self.request.method == 'GET':
            required_permission = 'view_secondmodel'
        elif self.request.method == 'PATCH':
            required_permission = 'update_secondmodel'
        elif self.request.method == 'DELETE':
            required_permission = 'delete_secondmodel'

        return get_objects_for_user(self.request.user, required_permission, klass=SecondModel)
序列化程序

class FirstModel(models.Model):
    id = models.AutoField(primary_key=True, name='id', db_column='id')
    name = models.CharField(max_length=255, blank=True, null=True)

    class Meta:
        app_label = 'choices'

        permissions = (
            ('view_firstmodel', 'Can view firstmodel'),
            ('update_firstmodel', 'Can update firstmodel')
        )


class SecondModel(models.Model):
    id = models.AutoField(primary_key=True, name='id', db_column='id')
    name = models.CharField(max_length=255, blank=True, null=True)
    parent_firstmodel = models.ForeignKey(FirstModel, related_name='secondmodel_objects')

    class Meta:
        app_label = 'choices'

        permissions = (
            ('view_secondmodel', 'Can view secondmodel'),
            ('update_secondmodel', 'Can update secondmodel')
        )
class SecondModelSerializer(serializers.ModelSerializer):

    parent_firstmodel = serializers.PrimaryKeyRelatedField()

    class Meta:
        model = SecondModel
        fields = ('id', 'name', 'parent_firstmodel')


class FirstModelSerializer(serializers.ModelSerializer):

    secondmodel_objects = SecondModelSerializer(many=True, allow_add_remove=True)

    class Meta:
        model = FirstModel
        fields = ('id', 'name', 'secondmodel_objects')
class FirstModelList(ListCreateAPIView):
    serializer_class = FirstModelSerializer
    model = FirstModel

    def post_save(self, obj, created=False):
        assign_perm('view_firstmodel', self.request.user, obj)
        assign_perm('update_firstmodel', self.request.user, obj)
        assign_perm('delete_firstmodel', self.request.user, obj)

    def get_queryset(self):
        return get_objects_for_user(self.request.user, 'view_firstmodel', klass=FirstModel)

class FirstModelDetail(RetrieveDestroyAPIView):
    serializer_class = FirstModelSerializer
    model = FirstModel

    def get_queryset(self):

        if self.request.method == 'GET':
            required_permission = 'view_firstmodel'
        elif self.request.method == 'PATCH':
            required_permission = 'update_firstmodel'
        elif self.request.method == 'DELETE':
            required_permission = 'delete_firstmodel'

        return get_objects_for_user(self.request.user, required_permission, klass=FirstModel)

class SecondModelList(ListCreateAPIView):
    serializer_class = SecondModelSerializer
    model = SecondModel

    def post_save(self, obj, created=False):
        assign_perm('view_secondmodel', self.request.user, obj)
        assign_perm('update_secondmodel', self.request.user, obj)
        assign_perm('delete_secondmodel', self.request.user, obj)

    def get_queryset(self):
        return get_objects_for_user(self.request.user, 'view_secondmodel', klass=SecondModel)


class SecondModelDetail(RetrieveDestroyAPIView):
    serializer_class = SecondModelSerializer
    model = SecondModel

    def get_queryset(self):

        if self.request.method == 'GET':
            required_permission = 'view_secondmodel'
        elif self.request.method == 'PATCH':
            required_permission = 'update_secondmodel'
        elif self.request.method == 'DELETE':
            required_permission = 'delete_secondmodel'

        return get_objects_for_user(self.request.user, required_permission, klass=SecondModel)
视图

class FirstModel(models.Model):
    id = models.AutoField(primary_key=True, name='id', db_column='id')
    name = models.CharField(max_length=255, blank=True, null=True)

    class Meta:
        app_label = 'choices'

        permissions = (
            ('view_firstmodel', 'Can view firstmodel'),
            ('update_firstmodel', 'Can update firstmodel')
        )


class SecondModel(models.Model):
    id = models.AutoField(primary_key=True, name='id', db_column='id')
    name = models.CharField(max_length=255, blank=True, null=True)
    parent_firstmodel = models.ForeignKey(FirstModel, related_name='secondmodel_objects')

    class Meta:
        app_label = 'choices'

        permissions = (
            ('view_secondmodel', 'Can view secondmodel'),
            ('update_secondmodel', 'Can update secondmodel')
        )
class SecondModelSerializer(serializers.ModelSerializer):

    parent_firstmodel = serializers.PrimaryKeyRelatedField()

    class Meta:
        model = SecondModel
        fields = ('id', 'name', 'parent_firstmodel')


class FirstModelSerializer(serializers.ModelSerializer):

    secondmodel_objects = SecondModelSerializer(many=True, allow_add_remove=True)

    class Meta:
        model = FirstModel
        fields = ('id', 'name', 'secondmodel_objects')
class FirstModelList(ListCreateAPIView):
    serializer_class = FirstModelSerializer
    model = FirstModel

    def post_save(self, obj, created=False):
        assign_perm('view_firstmodel', self.request.user, obj)
        assign_perm('update_firstmodel', self.request.user, obj)
        assign_perm('delete_firstmodel', self.request.user, obj)

    def get_queryset(self):
        return get_objects_for_user(self.request.user, 'view_firstmodel', klass=FirstModel)

class FirstModelDetail(RetrieveDestroyAPIView):
    serializer_class = FirstModelSerializer
    model = FirstModel

    def get_queryset(self):

        if self.request.method == 'GET':
            required_permission = 'view_firstmodel'
        elif self.request.method == 'PATCH':
            required_permission = 'update_firstmodel'
        elif self.request.method == 'DELETE':
            required_permission = 'delete_firstmodel'

        return get_objects_for_user(self.request.user, required_permission, klass=FirstModel)

class SecondModelList(ListCreateAPIView):
    serializer_class = SecondModelSerializer
    model = SecondModel

    def post_save(self, obj, created=False):
        assign_perm('view_secondmodel', self.request.user, obj)
        assign_perm('update_secondmodel', self.request.user, obj)
        assign_perm('delete_secondmodel', self.request.user, obj)

    def get_queryset(self):
        return get_objects_for_user(self.request.user, 'view_secondmodel', klass=SecondModel)


class SecondModelDetail(RetrieveDestroyAPIView):
    serializer_class = SecondModelSerializer
    model = SecondModel

    def get_queryset(self):

        if self.request.method == 'GET':
            required_permission = 'view_secondmodel'
        elif self.request.method == 'PATCH':
            required_permission = 'update_secondmodel'
        elif self.request.method == 'DELETE':
            required_permission = 'delete_secondmodel'

        return get_objects_for_user(self.request.user, required_permission, klass=SecondModel)
事实上,在secondmodel中没有检查到parent\u firstmodel字段引用了用户有权访问的对象(比如查看权限)

假设我们有2个用户,每个用户创建了一个firstmodel对象:

{
   id: 1,
   name: "user1 object firstmodel",
   secondmodel_objects: []
}

{
   id: 2,
   name: "user2 object firstmodel",
   secondmodel_objects: []
}
现在,用户2可以很好地创建第二个模型对象,如下所示:

{
    name: "user2 object secondmodel",
    parent_firstmodel: 1
}
所以基本上,他把一些东西附加到一个他没有权限的对象上。当然,我可以在post方法中检查这个具体案例,但我觉得它不是正确的地方。我更愿意说,这些检查的正确位置是序列化程序中的某个地方


我错过什么了吗?任何人都可以分享一些关于如何正确管理的经验?

您是否使用Django Rest框架?是的。哎哟,我忘了说清楚,对不起。