Django 有条件地限制字段更新 问题
假设我有这样一个模型和一个视图集:Django 有条件地限制字段更新 问题,django,django-rest-framework,Django,Django Rest Framework,假设我有这样一个模型和一个视图集: class Employee(models.Model): name = models.CharField(max_length=100) salary = models.PositiveIntegerField() class EmployeeViewSet(viewsets.ModelViewSet): model = Employee 我希望能够根据用户发出的请求限制字段更新 例如,员工可以更改姓名,但不能更改工资;另一方面,
class Employee(models.Model):
name = models.CharField(max_length=100)
salary = models.PositiveIntegerField()
class EmployeeViewSet(viewsets.ModelViewSet):
model = Employee
我希望能够根据用户发出的请求限制字段更新
例如,员工可以更改姓名,但不能更改工资;另一方面,经理可以同时更改员工的工资和姓名
我还需要提供适当的HTTP状态代码,指示特定字段的更改是禁止的,例如,如果一名员工将一个有效负载的薪资字段更改为403而不是200 OK
到目前为止我试过的东西
我尝试根据请求的用户更改序列化程序,并创建了几个不同的序列化程序,每个序列化程序指定不同的只读字段:
class EmployeeRestrictedSerializer(serializers.HyperlinkedModelSerializer):
class Meta(object):
model = Employee
fields = ('name', 'salary')
read_only_fields = ('salary',)
class EmployeeViewSet(viewsets.ModelViewSet):
model = Employee
def get_serializer_class(self):
if not self.request.user.is_staff:
return EmployeeRestrictedSerializer
return super(EmployeeViewSet, self).get_serializer_class()
这种方法通过完全忽略PUT有效负载中的salary字段来防止更改salary。如果名称有效,则返回200 OK(而不是403 FORBIDDEN),这使得用户相信他也设法更改了工资,但事实并非如此
我发现一个邮件列表也有类似的问题,尽管它还没有得到回复。我认为您不需要两个序列化程序 我会这样做: -创建自定义权限类- -更新时使用PATCH而不是PUT,因为PATCH允许从请求中遗漏某些字段 -在has_object_permission方法中,检查您的用户类型并返回适当的响应:
def has_object_permission(self, request, view, obj):
if request.user is manager:
return True
# Employee must not try to modify 'salary' field.
salary = request.DATA.get('salary', None)
return salary is None
当员工试图更改薪资字段时,默认情况下将返回403禁止
当然,如果您使用的是django模板,在我看来,更好的方法是在“employee”用户的模板中将该字段设置为只读