密码重置确认/密码重置请求-Django Rest api

问题描述 投票:0回答:1

我正在尝试重置密码功能。当我收到需要更改密码的用户电子邮件并成功向用户发送电子邮件以重置它(通过邮递员)时,我能够发出密码重置请求。问题是当我打开重置邮件时,它会指向密码重置确认用户在哪里输入新密码以替换数据库中的旧密码。我无法同时使用 GET 和 POST 方法处理它。GET 是显示字段的位置用户可以输入新密码和 POST 来发布请求和更新自定义用户模型。

序列化程序.py

from rest_framework import serializers
from django.contrib.auth.hashers import make_password

from .models import CustomUser


class SignUpUserSerialzer(serializers.ModelSerializer):

    password = serializers.CharField(max_length=100, write_only=True)

    def validate_password(self, password):
        return make_password(password)

    class Meta:
        model = CustomUser
        fields = '__all__'

class ChangePasswordSerializer(serializers.Serializer):
    model = CustomUser

    """
    password = serializers.CharField(max_length=100, write_only=True)

    def validate_password(self, password):
        return make_password(password)
    
    class Meta:
        model = CustomUser
        fields = ['password']

urls.py

from django.urls import path,include
from . import views
# from .views import ChangePasswordView
urlpatterns = [
   path('register/', views.register, name='register'),
   path('login/', views.custom_login, name='login'),
   path('logout/', views.custom_logout, name='logout'),
   path('user/', views.user_profile, name='user_profile'),
   path('activate/<uidb64>/<token>', views.activate, name='activate'),
   path("passwordreset/", views.password_reset_request, name="password_reset"),
   path('reset/<uidb64>/<token>/', views.passwordResetConfirm, name='password_reset_confirm'),

]

模型..py

自定义用户类(抽象用户):

email = models.EmailField(unique=True)


def __str__(self):
    return self.username

views.py

@api_view(['POST'])
def register(request):
    # if request.method == "POST":
        # form = UserRegistrationForm(request.POST,request.FILES)
    userser = SignUpUserSerialzer(data=request.data)
    print('hello0')
    if userser.is_valid():
        print('hello1')
        user = userser.save(is_active = False)
        print('hello2')
        activateEmail(request, user, userser.validated_data['email'])
        print('hello3')
        return Response(userser.data)

    else:
        return Response(status=status.HTTP_404_NOT_FOUND)


@api_view(['POST'])
def custom_login(request):
    # if request.user.is_authenticated:
    #     return redirect(reverse('home'))

    username=request.data['username']
    password=request.data['password']
    print(username)
    print(password)
    print('login1')
    user = authenticate(username=username, password=password)
    print('login2')
    print(user)
    if user is not None:
        login(request, user)
        return Response({"user": user.id})

    else:
        return Response("error")

@api_view(['POST'])
def custom_logout(request):
    logout(request)
    return Response("logged out")


def activateEmail(request, user, to_email):
    mail_subject = 'Activate your user account.'
    message = render_to_string('template_activate_account.html', {
        'user': user.username,
        'domain': get_current_site(request).domain,
        'uid': urlsafe_base64_encode(force_bytes(user.pk)),
        'token': account_activation_token.make_token(user),
        'protocol': 'https' if request.is_secure() else 'http'
    })
    email = EmailMessage(mail_subject, message, to=[to_email])
    if email.send():
        messages.success(request, f'Dear <b>{user}</b>, please go to you email <b>{to_email}</b> inbox and click on \
            received activation link to confirm and complete the registration. <b>Note:</b> Check your spam folder.')
    else:
        messages.error(request,
            f'Problem sending confirmation email to {to_email}, check if you typed it correctly.')

@api_view(['GET'])
def activate(request, uidb64, token):
    User = get_user_model()
    try:
        uid = force_str(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except(TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None

    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.save()
        return Response('account activated')
    else:
        return Response('activation failed')

@api_view(['GET'])
def user_profile(request):
    user = request.user
    posts = Posts.objects.filter(user=user)
    serial = PostsSerializer(posts,many=True)

    return Response(serial.data)



@api_view(['POST'])
def password_reset_request(request):
    if request.method == 'POST':
            print("pass1")
        # form = PasswordResetForm(request.POST)
        # if form.is_valid():
            user_email = request.data['email']
            print("pass2")
            
            associated_user = get_user_model().objects.filter(Q(email=user_email)).first()
            print("pass3")

            if associated_user:
                subject = "Password Reset request"
                message = render_to_string("template_reset_password.html", {
                    'user': associated_user,
                    'domain': get_current_site(request).domain,
                    'uid': urlsafe_base64_encode(force_bytes(associated_user.pk)),
                    'token': account_activation_token.make_token(associated_user),
                    "protocol": 'https' if request.is_secure() else 'http'
                })
                email = EmailMessage(subject, message, to=[associated_user.email])
                print("pass4")
                if email.send():
                    messages.success(request,
                        """
                        <h2>Password reset sent</h2><hr>
                        <p>
                            We've emailed you instructions for setting your password, if an account exists with the email you entered. 
                            You should receive them shortly.<br>If you don't receive an email, please make sure you've entered the address 
                            you registered with, and check your spam folder.
                        </p>
                        """
                    )
                    print("pass5")
                    return Response("Password reset sent")
                else:
                    return Response("reset sent")

@api_view(['GET','POST'])
def passwordResetConfirm(request, uidb64, token):
    User = get_user_model()
    try:
        uid = force_str(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
        print("confr0")
    except:
        user = None
    print("confr1")
    print(user)

    if user is not None and account_activation_token.check_token(user, token):
        print("enter1")
        if request.method == 'POST':
            passser = ChangePasswordSerializer(data=request.data)
            print("enter2")

            # form = SetPasswordForm(user, request.POST)
            # password=request.data['password']
            if passser.is_valid():
                print('passre1')
                passw = passser.save()
                print('passre2')
                # form.save()
                return Response("pass succefuly changed")
            else:
                return Response("error")
        else:
            passser = ChangePasswordSerializer()  
            return Response(passser.data)  

    else:
        return Response(" major error")

模型.py

class CustomUser(AbstractUser):


    email = models.EmailField(unique=True)


    def __str__(self):
        return self.username
python django rest django-rest-framework django-views
1个回答
0
投票
  1. 你没有阅读 DRF 的文档,这是 DRF 的链接 https://www.django-rest-framework.org

  2. request.data
    返回
    request body
    的解析内容。这类似于标准的
    request.POST
    request.FILES
    属性。你可以在这里查看https://www.django-rest-framework.org/api-guide/requests/

  3. Rest Framework 提供了一个 Api View,它继承了 Django 的 View 类。这是链接https://www.django-rest-framework.org/api-guide/views/

  4. REST framework 提供的

    Generic views
    允许您快速构建与您的数据库模型紧密映射的API 视图。 https://www.django-rest-framework.org/api-guide/generic-views/

  5. ViewSet 类只是一种基于类的视图,它不提供任何方法处理程序,例如 .get() 或 .post(),而是提供诸如 .list() 和 .create() 等操作。 https://www.django-rest-framework.org/api-guide/viewsets/

重要:您没有调用

serializer.save()
这就是用户未保存在数据库中的原因。

如果你想在 Rest API 中实现密码重置:这是你可以检查的链接:https://github.com/tanveer-ahmad74/Dummy

© www.soinside.com 2019 - 2024. All rights reserved.