Lin*_*nio 1 django django-rest-framework
我正在尝试使用 Django Rest Framework 强制执行权限,其中特定用户无法发布包含不是他的用户 ID 的对象。
例如,我不希望用户使用另一个 id 发布反馈。
我的模型是这样的:
class Feedback(Model):
user = ForeignKey(User)
...
Run Code Online (Sandbox Code Playgroud)
我尝试对我的视图授予权限,该权限会将feedback.user.id 与request.user.id 进行比较,正确处理对象上的帖子并返回false,但它仍在发布我的对象......为什么?
风景
class FeedbackViewSet(ModelViewSet):
model = Feedback
permission_classes = (IsSelf,)
serializer_class = FeedbackSerializer
def get_queryset(self):
....
Run Code Online (Sandbox Code Playgroud)
许可
class IsSelf(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
#return eval(obj.user.id) == request.user.id
return False
Run Code Online (Sandbox Code Playgroud)
我已经注释了该行以显示问题所在。该函数再次被正确调用并返回 False,但没有引发 PermissionDenied。在此期间,我想知道这是否真的是实现这种行为的方式,如果不是,那会是什么......?谢谢。
Your problem is that has_object_permission is only called if you're trying to access a certain object. So on creation it is never actually used.
I'd suggest you do the check on validation. Example:
class FeedbackSerializer(HyperlinkedModelSerializer):
def validate(self, attrs):
user = self.context['request'].user
if attrs['user'].id != user.id:
raise ValidationError('Some exception message')
return attrs
Run Code Online (Sandbox Code Playgroud)
If you have some other super serializer class then just change it.
Now that I think of it if the user field must always be the posting user, then you should just make that field read-only and set it on pre_save() in the viewset class.
class FeedbackViewSet(ModelViewSet):
def pre_save(self, obj, *args, **kwargs):
if self.action == 'create':
obj.user = self.request.user
Run Code Online (Sandbox Code Playgroud)
And in the serializer set the user field read-only
class FeedbackSerializer(HyperlinkedModelSerializer):
user = serializers.HyperlinkedRelatedField(view_name='user-detail', read_only=True)
....
Run Code Online (Sandbox Code Playgroud)