Поиск URL не работает при обновлении и извлечении
В url /users/*username
я должен иметь возможность получить доступ к каждому пользователю по его имени пользователя, проблема в том, что это не работает так, как должно, не имеет значения, что я пишу в *username
, он будет обновлять/удалять текущего зарегистрированного пользователя.
Пример: Я могу обновить пользователя "admin" через /users/123/, даже если 123 явно не является администратором или любым другим существующим пользователем.
Вот представление пользователя с методами, которые не работают так, как я задумал:
class UserViewSet(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
serializer_class = UserSerializer
lookup_field = 'username'
queryset = User.objects.all()
def get_permissions(self):
if self.action in ['signup', 'login',]:
permissions = [AllowAny]
elif self.action in ['retrieve', 'update', 'destroy']:
permissions = [IsAuthenticated, IsSameUser]
else:
permissions = [IsAuthenticated]
return [p() for p in permissions]
def retrieve(self, request, *args, **kwargs):
response = super(UserViewSet, self).retrieve(request, *args, **kwargs)
data = response.data
return Response(data=data, status=status.HTTP_200_OK)
def update(self, request, *args, **kwargs):
serializer = UserModelSerializer(request.user, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
будет обновлять/удалять текущего зарегистрированного пользователя.
Конечно
Ваш метод обновления:
def update(self, request, *args, **kwargs):
serializer = UserModelSerializer(request.user, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
где request.user
- вошедший в систему пользователь.
Правильный код выглядит примерно так:
class UserViewSet(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
serializer_class = UserSerializer
lookup_field = 'username'
queryset = User.objects.all()
...
def update(self, url_username, request, *args, **kwargs):
try:
user_object = self.queryset.get(username=url_username)
except User.DoesNotExist:
Response({'error': 'not found'}, status=404)
serializer = UserModelSerializer(user_object, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
Также вам нужно добавить url_username
в URL путь:
urlpatterns = [
...,
path('users/<str:url_username>', update_user)
]
Здесь
user_object
- пользователь, которого вы хотите обновитьrequest.data
- это новые данные, которые вы хотите установить для существующего пользователяurl_username
- это*username
часть в/users/*username
для получения точного пользователя
в вашем сериализаторе UserSerializer необходимо добавить этот мета-класс:
class Meta:
lookup_field = 'username'