Django 对象级权限
我想知道对象级权限的正确位置。我正在使用django guardian与post_save hook进行此操作: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
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框架?是的。哎哟,我忘了说清楚,对不起。