Skip to content

Instantly share code, notes, and snippets.

@gengue
Last active February 2, 2023 03:50
Show Gist options
  • Save gengue/a914bc1540383bfa5e1374db3df10efd to your computer and use it in GitHub Desktop.
Save gengue/a914bc1540383bfa5e1374db3df10efd to your computer and use it in GitHub Desktop.
Django Rest Framework user endpoint with change password
# -*- 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)
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))]
# -*- 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)
@shanemgrey
Copy link

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

    @detail_route(methods=['post'], permission_classes=[IsSuperuserOrIsSelf], url_path='change-password')
    def set_password(self, request, pk=None):

Thanks again for posting this gist and getting me most of the way there!

@nosarthur
Copy link

user = self.get_object() is missing in views.py::UserViewSet::set_password

@Aubrey-t
Copy link

Anyone has something similar for reset password instead

@tsunday
Copy link

tsunday commented Aug 27, 2018

@KevinPercy
Copy link

I added @nosarthur response to my code and replaced @list_route with @action and it worked!

@VivienGiraud
Copy link

Hi,
Thanks for it!
Could you share the code for IsSuperuserOrIsSelf ? Seems interresting to me.

@gengue
Copy link
Author

gengue commented Dec 16, 2020

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