@action got an unexpected keyword argument 'id'
class CustomUserViewSet(UserViewSet):
serializer_class = UserSerializer
pagination_class = PageNumberPagination
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
queryset = User.objects.all()
return queryset
@action(detail=False, methods=['put', 'delete'], url_path='me/avatar')
def set_avatar(self, request):
if request.method == 'PUT':
serializer = SetAvatarSerializer(
request.user,
data=request.data,
partial=True
)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(status=status.HTTP_200_OK)
user = request.user
user.avatar.delete()
user.save()
return Response(status=status.HTTP_204_NO_CONTENT)
@action(detail=True, methods=['post', 'delete'], url_path='subscribe')
def set_or_delete_subscribe(self, request, pk=None):
user = request.user
user_to_subscribe = self.kwargs['id']
if request.method == 'POST':
_, created = Subscription.objects.get_or_create(user=user, subscribed=user_to_subscribe)
if created:
return Response(status=status.HTTP_201_CREATED)
return Response(status=status.HTTP_400_BAD_REQUEST)
if request.method == 'DELETE':
subscription = Subscription.objects.filter(user=user, subscribed=user_to_subscribe).delete()
if subscription:
return Response(status=status.HTTP_204_NO_CONTENT)
return Response(status=status.HTTP_400_BAD_REQUEST)
model of Subscription
class Subscription(models.Model):
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='subscriptions'
)
subscribed = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='subscribed'
)
class Meta:
constraints = [
models.UniqueConstraint(fields=['user', 'subscribed'], name='unique_subscription')
]
urls
router = DefaultRouter()
router.register(r'tags', TagViewSet, basename='tags')
router.register(r'recipes', RecipeViewSet, basename='recipes')
router.register(r'ingredients', IngridientsViewSet, basename='ingredients')
router.register(r'users', CustomUserViewSet, basename='users')
TypeError: set_or_delete_subscribe() got an unexpected keyword argument 'id' [10/Mar/2025 08:38:23] "POST /api/users/11/subscribe/ HTTP/1.0" 500 88724
I can't figure out why get_object() expects id and doesn't accept pk ? Ьaybe I'm missing something, but I can't catch it. I need to subscribe to a user or delete them if already subscribed.
DRF ViewSets with detail=True use pk, not id. You should to change:
user_to_subscribe = get_object_or_404(User, pk=pk)
Correct code:
def set_or_delete_subscribe(self, request, pk=None):
user = request.user
user_to_subscribe = get_object_or_404(User, pk=pk)
if request.method == 'POST':
_, created = Subscription.objects.get_or_create(user=user, subscribed=user_to_subscribe)
if created:
return Response(status=status.HTTP_201_CREATED)
return Response(status=status.HTTP_400_BAD_REQUEST)
if request.method == 'DELETE':
subscription = Subscription.objects.filter(user=user, subscribed=user_to_subscribe).delete()
if subscription:
return Response(status=status.HTTP_204_NO_CONTENT)
return Response(status=status.HTTP_400_BAD_REQUEST)`