Last active
February 2, 2023 03:50
-
-
Save gengue/a914bc1540383bfa5e1374db3df10efd to your computer and use it in GitHub Desktop.
Django Rest Framework user endpoint with change password
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from __future__ import absolute_import, unicode_literals | |
from rest_framework import serializers | |
from .models import User | |
class UserSerializer(serializers.ModelSerializer): | |
""" | |
User accounts serializer | |
""" | |
class Meta: | |
model = User | |
fields = ('id', 'username', 'email', 'first_name', 'last_name', | |
'is_active','is_staff', 'is_superuser', 'date_joined',) | |
read_only_fields = ('username', 'auth_token', 'date_joined',) | |
class PasswordSerializer(serializers.Serializer): | |
""" | |
Serializer for password change endpoint. | |
""" | |
old_password = serializers.CharField(required=True) | |
new_password = serializers.CharField(required=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf.urls import url, include | |
from django.conf import settings | |
from django.views import defaults | |
from django.conf.urls.static import static | |
from django.contrib import admin | |
from rest_framework.documentation import include_docs_urls | |
from rest_framework.routers import DefaultRouter | |
from users.views import UserViewSet | |
router = DefaultRouter() | |
router.register(r'users', UserViewSet) | |
urlpatterns = [ | |
url(r'^admin/', admin.site.urls), | |
url(r'^api/v1/', include(router.urls)), | |
url(r'^api/v1/docs/', include_docs_urls(title='MY API')) | |
] | |
if settings.DEBUG: | |
# static/media files | |
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) | |
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) | |
import debug_toolbar | |
urlpatterns += [url(r'^__debug__/', include(debug_toolbar.urls))] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from __future__ import absolute_import, unicode_literals | |
from rest_framework import viewsets, mixins, status | |
from rest_framework.response import Response | |
from rest_framework.request import Request | |
from rest_framework.decorators import list_route | |
from rest_framework.views import APIView | |
from .models import User | |
from .permissions import IsSuperuserOrIsSelf | |
from .serializers import UserSerializer, PasswordSerializer | |
class UserViewSet(mixins.ListModelMixin, | |
mixins.RetrieveModelMixin, | |
mixins.UpdateModelMixin, | |
viewsets.GenericViewSet): | |
""" | |
list: | |
Return a list of all the existing users. | |
read: | |
Return the given user. | |
me: | |
Return authenticated user. | |
""" | |
queryset = User.objects.all() | |
serializer_class = UserSerializer | |
permission_classes = (IsSuperuserOrIsSelf,) | |
@list_route(methods=['put'], serializer_class=PasswordSerializer) | |
def set_password(self, request): | |
serializer = PasswordSerializer(data=request.data) | |
if serializer.is_valid(): | |
if not user.check_password(serializer.data.get('old_password')): | |
return Response({'old_password': ['Wrong password.']}, | |
status=status.HTTP_400_BAD_REQUEST) | |
# set_password also hashes the password that the user will get | |
user.set_password(serializer.data.get('new_password')) | |
user.save() | |
return Response({'status': 'password set'}, status=status.HTTP_200_OK) | |
return Response(serializer.errors, | |
status=status.HTTP_400_BAD_REQUEST) |
user = self.get_object()
is missing in views.py::UserViewSet::set_password
Anyone has something similar for reset password instead
@Aubrey-t, you should check this one: https://pypi.org/project/django-rest-passwordreset/
I added @nosarthur response to my code and replaced @list_route with @action and it worked!
Hi,
Thanks for it!
Could you share the code for IsSuperuserOrIsSelf
? Seems interresting to me.
Thank you all! this code is from 5 years ago I will try updated soon
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Solved:
The key was finding the part of the DRF docs that indicated the route that is created when using this decorator.
http://www.django-rest-framework.org/api-guide/routers/#extra-link-and-actions
The change to my code was
Thanks again for posting this gist and getting me most of the way there!