2016-08-09 7 views
12

मैं यह पूछना चाहता हूं कि निम्नलिखित कोड पासवर्ड अपडेट कर रहा है लेकिन मैं वर्तमान पासवर्ड पुष्टिकरण प्रक्रिया के बाद पासवर्ड अपडेट करना चाहता हूं। तो मुझे इसके लिए क्या जोड़ना चाहिए? धन्यवाद।Django Rest Framework में उपयोगकर्ता पासवर्ड कैसे अपडेट करें?

class UserPasswordSerializer(ModelSerializer): 

    class Meta: 
     model = User 
     fields = [ 
      'password' 
     ] 

     extra_kwargs = { 
      "password": {"write_only": True}, 
     } 

    def update(self, instance, validated_data): 
     for attr, value in validated_data.items(): 
      if attr == 'password': 
       instance.set_password(value) 
      else: 
       setattr(instance, attr, value) 
     instance.save() 
     return instance 

उत्तर

27

मेरा मानना ​​है कि मॉडेलरियलाइज़र का उपयोग करना एक ओवरकिल हो सकता है। यह सरल धारावाहिक & दृश्य काम करना चाहिए।

class ChangePasswordSerializer(serializers.Serializer): 
    """ 
    Serializer for password change endpoint. 
    """ 
    old_password = serializers.CharField(required=True) 
    new_password = serializers.CharField(required=True) 


class ChangePasswordView(UpdateAPIView): 
    """ 
    An endpoint for changing password. 
    """ 
    serializer_class = ChangePasswordSerializer 
    model = UserProfile 
    permission_classes = (IsAuthenticated,) 

    def get_object(self, queryset=None): 
     obj = self.request.user 
     return obj 

    def update(self, request, *args, **kwargs): 
     self.object = self.get_object() 
     serializer = self.get_serializer(data=request.data) 

     if serializer.is_valid(): 
      # Check old password 
      if not self.object.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 
      self.object.set_password(serializer.data.get("new_password")) 
      self.object.save() 
      return Response("Success.", status=status.HTTP_200_OK) 

     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 
+0

आपको क्यों लगता है कि मॉडलसेरियलाइज़र होगा overkill? इस तरह आपके पास दृश्य अद्यतन विधि में बहुत सी धारावाहिक कोड है। क्या वो बेहतर है? –

9

@ Yiğit Güler एक अच्छा जवाब है, धन्यवाद, लेकिन यह कुछ मामूली अंक में बेहतर हो सकता है।

जब तक आप वास्तव में UpdateModelMixin साथ काम करता है नहीं है, लेकिन सीधे अनुरोध उपयोगकर्ता उदाहरण के साथ, आप एक UpdateAPIView उपयोग करने की आवश्यकता नहीं है। एक साधारण APIView पर्याप्त है।

साथ ही, जब पासवर्ड बदल जाता है, तो आप कुछ यादृच्छिक सामग्री के साथ 200 के बजाय status.HTTP_204_NO_CONTENT वापस कर सकते हैं।

वैसे, सहेजने से पहले अपने नए पासवर्ड को सत्यापित करने के लिए मत भूलना। यह बहुत बुरा है अगर आप अपडेट पर "पासवर्ड" को अनुमति देते हैं, जबकि आप नहीं बनाते हैं।

तो मैं अपने प्रोजेक्ट में निम्न कोड का उपयोग करें:

class UpdatePassword(APIView): 
    """ 
    An endpoint for changing password. 
    """ 
    permission_classes = (permissions.IsAuthenticated,) 

    def get_object(self, queryset=None): 
     return self.request.user 

    def put(self, request, *args, **kwargs): 
     self.object = self.get_object() 
     serializer = ChangePasswordSerializer(data=request.data) 

     if serializer.is_valid(): 
      # Check old password 
      old_password = serializer.data.get("old_password") 
      if not self.object.check_password(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 
      self.object.set_password(serializer.data.get("new_password")) 
      self.object.save() 
      return Response(status=status.HTTP_204_NO_CONTENT) 

     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 
+0

बेहतर लगता है लेकिन आप अभी भी एक एपीआई व्यू के बजाय जेनेरिकैपिव्यू का उपयोग करेंगे क्योंकि आप एक सीरिएलाइज़र का उपयोग करते हैं। कुछ दस्तावेज lib इस ज्ञान का उपयोग करेंगे (दृश्य को जानने के लिए एक धारावाहिक का उपयोग करता है) :) –

5

आप उपयोगकर्ता को बचाने के बाद, आप उपयोगकर्ता लॉग ऑन रहता है कि यह सुनिश्चित करना चाहते हो सकता है:

from django.contrib.auth.password_validation import validate_password 

class ChangePasswordSerializer(serializers.Serializer): 
    """ 
    Serializer for password change endpoint. 
    """ 
    old_password = serializers.CharField(required=True) 
    new_password = serializers.CharField(required=True) 

    def validate_new_password(self, value): 
     validate_password(value) 
     return value 

और दृश्य के लिए में (django == 1.7 के बाद उपयोगकर्ता स्वचालित रूप से पासवर्ड परिवर्तन पर लॉग आउट होता है):

from django.contrib.auth import update_session_auth_hash 

# make sure the user stays logged in 
update_session_auth_hash(request, self.object)