我正在尝试重置密码功能。当我收到需要更改密码的用户电子邮件并成功向用户发送电子邮件以重置它(通过邮递员)时,我能够发出密码重置请求。问题是当我打开重置邮件时,它会指向密码重置确认用户在哪里输入新密码以替换数据库中的旧密码。我无法同时使用 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
你没有阅读 DRF 的文档,这是 DRF 的链接 https://www.django-rest-framework.org
request.data
返回request body
的解析内容。这类似于标准的 request.POST
和 request.FILES
属性。你可以在这里查看https://www.django-rest-framework.org/api-guide/requests/
Rest Framework 提供了一个 Api View,它继承了 Django 的 View 类。这是链接https://www.django-rest-framework.org/api-guide/views/
REST framework 提供的
Generic views
允许您快速构建与您的数据库模型紧密映射的API 视图。 https://www.django-rest-framework.org/api-guide/generic-views/
ViewSet 类只是一种基于类的视图,它不提供任何方法处理程序,例如 .get() 或 .post(),而是提供诸如 .list() 和 .create() 等操作。 https://www.django-rest-framework.org/api-guide/viewsets/
重要:您没有调用
serializer.save()
这就是用户未保存在数据库中的原因。
如果你想在 Rest API 中实现密码重置:这是你可以检查的链接:https://github.com/tanveer-ahmad74/Dummy