Django REST Framework:基于类视图移除主键的类式实现方案问询
Got it, let's fix this class-based view issue for you. The problem here is that RetrieveUpdateAPIView expects a URL parameter (like pk) by default to fetch the object, but you want to use request.user instead. Here's how to adjust your class view to make it work while keeping all DRF's built-in features:
The Correct Class-Based Solution
Instead of overriding get_queryset, you need to override the get_object method. This method is responsible for fetching the single object the view operates on, and by rewriting it, you can bypass the default logic that looks for a pk in the URL.
Here's your updated UserProfileView:
from rest_framework import generics, permissions from rest_framework.exceptions import APIException from .models import UserProfile from .serializers import UserProfileSerializer from .permissions import IsOwnerOrReadOnly class UserProfileView(generics.RetrieveUpdateAPIView): serializer_class = UserProfileSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) # Keep pagination if you need it later; single objects will still work with it # pagination_class = LimitTenPagination def get_object(self): try: # Directly fetch the profile linked to the current authenticated user return UserProfile.objects.get(user=self.request.user) except UserProfile.DoesNotExist: raise APIException('No profile linked with this user')
Update Your URL Configuration
Use the same route you had for your function view, since we no longer need a pk parameter:
# In api/urls.py url(r'^me/$', views.UserProfileView.as_view())
Why This Works (And Why Your First Attempt Failed)
The default get_object method in RetrieveUpdateAPIView does two things you don't want here:
- It looks for a URL keyword argument (like
pk) matching the view'slookup_field(default ispk). - It filters your queryset using that URL parameter to find the object.
By overriding get_object, you skip this entire logic and directly return the profile tied to request.user. This keeps all your existing DRF features intact:
- Your
permission_classeswill still validate access (sincerequest.useris available for checks likeIsOwnerOrReadOnly). - The
serializer_classwill correctly serialize the single profile object. - If you re-enable
pagination_classlater, DRF will automatically wrap the single object in a paginated response.
内容的提问来源于stack exchange,提问作者hemo

