You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:47:53