Django Rest Framework添加权限时遇AttributeError错误求助
解决DRF中
AttributeError: type object 'object' has no attribute 'id'权限错误 我在为Django Rest Framework项目添加权限时遇到错误:AttributeError: type object 'object' has no attribute 'id',相关代码及错误回溯如下:
相关代码
permissions.py
from rest_framework import permissions class UpdateOwnProfile(permissions.BasePermission): """Allow users to edit their own profile""" def has_object_permission(self, request, view, obj): """Check user is trying to edit their own profile""" if request.method in permissions.SAFE_METHODS: return True return object.id == request.user.id
UserProfile的views.py
class UserProfileViewSet(viewsets.ModelViewSet): """Handle creating and updating profiles""" serializer_class = serializers.UserProfileSerializer queryset = models.UserProfile.objects.all() authentication_classes = ( TokenAuthentication, ) permission_classes = ( permissions.UpdateOwnProfile, )
serializers.py
class UserProfileSerializer(serializers.ModelSerializer): """Serializes a user profile object""" class Meta: model = models.UserProfile fields = ("id", "email", "name", "password") extra_kwargs = { "password": { "write_only": True, "style": { "input_type": "password" }, } } def create(self, validated_data): """Create and return a new user""" user = models.UserProfile.objects.create_user( email=validated_data["email"], name=validated_data["name"], password=validated_data["password"], ) return user def update(self, instance, validated_data): """Handle updating user account""" if "password" in validated_data: password = validated_data.pop("password") instance.set_password(password) return super().update(instance, validated_data)
错误回溯
Traceback (most recent call last): File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 34, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 145, in _get_response response = self.process_exception_by_middleware(e, request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 143, in _get_response response = response.render() ^^^^^^^^^^^^^^^^^ File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/django/template/response.py", line 106, in render self.content = self.rendered_content ^^^^^^^^^^^^^^^^^^^^^ File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/rest_framework/response.py", line 72, in rendered_content ret = renderer.render(self.data, accepted_media_type, context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/rest_framework/renderers.py", line 733, in render context = self.get_context(data, accepted_media_type, renderer_context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/rest_framework/renderers.py", line 664, in get_context raw_data_put_form = self.get_raw_data_form(data, view, 'PUT', request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/rest_framework/renderers.py", line 552, in get_raw_data_form if not self.show_form_for_method(view, method, request, instance): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/rest_framework/renderers.py", line 444, in show_form_for_method view.check_object_permissions(request, obj) File "/Users/xxxx/Desktop/django-rest-tutorial/django/venv/lib/python3.11/site-packages/rest_framework/views.py", line 345, in check_object_permissions if not permission.has_object_permission(request, self, obj): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/xxxx/Desktop/django-rest-tutorial/django/profiles_api/permissions.py", line 13, in has_object_permission return object.id == request.user.id # If True, the user is authenticated, if False, the user has not permissions on that profile, he/she won't be able to make changes ^^^^^^^^^ AttributeError: type object 'object' has no attribute 'id'
解决方案
错误原因
在UpdateOwnProfile类的has_object_permission方法中,误用了Python内置的object类型(所有类的基类),而非方法参数传递的当前模型实例obj。object类型本身没有id属性,因此触发错误。
修改代码
将permissions.py中的return object.id == request.user.id改为return obj.id == request.user.id即可。
修改后的完整permissions.py代码:
from rest_framework import permissions class UpdateOwnProfile(permissions.BasePermission): """Allow users to edit their own profile""" def has_object_permission(self, request, view, obj): """Check user is trying to edit their own profile""" if request.method in permissions.SAFE_METHODS: return True return obj.id == request.user.id
逻辑说明
方法参数obj是当前请求对应的UserProfile模型实例,包含数据库存储的id字段;request.user.id是当前登录用户的ID。两者对比后,仅当用户编辑自身资料时返回True允许操作,否则拒绝修改,实现“仅允许用户编辑自身资料”的权限控制。
内容的提问来源于stack exchange,提问作者albdev
相关产品推荐
相关产品推荐

