我的python项目的url在这里: https://github.com/abylikhsanov/social
我正在尝试实施密码更改表单,因此用户可以更改其密码。我该如何实现它?应用程序应跟踪以前的密码,不应允许用户使用以前使用的密码。另外,我想实现重置密码功能。
答案 0 :(得分:4)
为什么不使用django的内置PasswordChangeForm(django.contrib.auth.forms)。
如果你喜欢它的工作方式,只需使用它,或者你可以创建一个继承PasswordChangeForm的新的
class PasswordChangeCustomForm(PasswordChangeForm):
error_css_class = 'has-error'
error_messages = {'password_incorrect':
"Το παλιό συνθηματικό δεν είναι σωστό. Προσπαθείστε ξανά."}
old_password = CharField(required=True, label='Συνθηματικό',
widget=PasswordInput(attrs={
'class': 'form-control'}),
error_messages={
'required': 'Το συνθηματικό δε μπορεί να είναι κενό'})
new_password1 = CharField(required=True, label='Συνθηματικό',
widget=PasswordInput(attrs={
'class': 'form-control'}),
error_messages={
'required': 'Το συνθηματικό δε μπορεί να είναι κενό'})
new_password2 = CharField(required=True, label='Συνθηματικό (Επαναλάβατε)',
widget=PasswordInput(attrs={
'class': 'form-control'}),
error_messages={
'required': 'Το συνθηματικό δε μπορεί να είναι κενό'})
稍后我将提供一个清理和保存方法的例子
有关详细信息,请参阅here
答案 1 :(得分:2)
您可以看到以下文档的更改密码部分。 How to change password in Django。 它的工作原理如下:
导航到manage.py
文件所在的项目
$ python manage.py shell
执行以下操作:
from django.contrib.auth.models import User
u = User.objects.get(username__exact='john')
u.set_password('new password')
u.save()
您必须制作一个表单集,然后在提交表单时执行此操作。
您还可以使用简单的manage.py
命令:
manage.py changepassword *username*
只需输入两次新密码即可。
对于问题的第二部分(用户无法选择旧密码),您可以创建一个表,用于存储用户的旧密码。当用户输入新密码时,您可以在该表中检查是否可以选择。 Django有一个函数check_password,用于比较两个密码。
答案 2 :(得分:2)
由于您使用自定义用户模型,实现该功能的一个好方法是创建一个新表单ChangePassword
:
class ChangePassword(forms.Form):
old_password=forms.PasswordField()
new_password=forms.PasswordField()
reenter_password=forms.PasswordField()
def clean(self):
new_password=self.cleaned_data.get('new_password')
reenter_password=self.cleaned_data.get('reenter_password')
#similarly old_password
if new_password and new_password!=reenter_password or new_password==old_password:
#raise error
#get the user object and check from old_password list if any one matches with the new password raise error(read whole answer you would know)
return self.cleaned_data #don't forget this.
您可以定义clean()
以检查两个密码是否匹配,并且输入的新密码与旧密码不同。
如果您不希望用户使用他们在选项之前使用的密码
根据您的型号,您不加密密码,因此选项1对您有好处。如果你想加密你可以为它选择sha256,库是passlib;只是搜索谷歌。
要实现选项1,只需在模型中添加一个字段,每当更改密码时,将旧密码附加到此字段内容。您可以使用CharField
,但其最大长度仅为255,而您可以选择textfield
,对于您的模型,它将是:
class Members(models.Model):
#rest fields..
old_passwords=models.TextField(blank=True,default='')
现在,在保存ChangePassword时,请使用已清理的数据更新成员密码:
def change_password(request):
if request.method=='POST':
form=ChangePassword(request.POST)
if form.is_valid():
new_pass=form.cleaned_data['new_password']
#get the current user object as user
if user.old_password=='':
#it's first time user is changing password
#populate our Members old_password_field
user.old_password=user.password
else:
user.old_password=user.old_password+','+user.password
user.password=new_password
user.save()
#do whatever you want to do man..
代码只是为了帮助您了解您需要做什么,您必须以自己的方式做事!
答案 3 :(得分:2)
如果容易的话,
from django.contrib.auth.forms import PasswordChangeForm
然后
class MyChangeFormPassword(PasswordChangeForm):
pass
您认为
def get(self, request):
instance_user = get_object_or_404(User, id=int(user_id))
form_edit_password = MyChangeFormPassword(instance_user)
context={'form_edit_password': form_edit_password}
return render(request, self.template_name, context)
在您的模板上
<div class="col-lg-4">
{{form_edit_password.old_password}}
</div>
<div class="col-lg-4">
{{form_edit_password.new_password1}}
</div>
<div class="col-lg-4">
{{form_edit_password.new_password2}}
</div>
您的帖子
form_edit_password = ChangePasswordForm(user, data=put)
if form_edit_password.is_valid():
form_edit_password.save()
return self.__succes_response(_('Password updated'))
else:
return self.__error_response([form_edit_password])
Django会为您做所有事情,不是吗?您可以在MyChangeFormPassword上编写自己的规则,以覆盖父方法,但这是一个很好的方法,
我正在为Django 3编写此代码。
答案 4 :(得分:0)
如果你看看https://github.com/django/django/blob/master/django/contrib/auth/views.py 您会注意到
password_reset采用名为
template_name的命名参数
def password_reset(request, is_admin_site=False,
template_name='registration/password_reset_form.html',
email_template_name='registration/password_reset_email.html',
password_reset_form=PasswordResetForm,
token_generator=default_token_generator,
post_reset_redirect=None):
因此与urls.py一样......
from django.conf.urls.defaults import *
from django.contrib.auth.views import password_reset
urlpatterns = patterns('',
(r'^/accounts/password/reset/$', password_reset, {'template_name': 'my_templates/password_reset.html'}),
...
django.contrib.auth.views.password_reset 将针对与&#39; / accounts / password / reset&#39; 匹配的网址与关键字参数< strong> template_name =&#39; my_templates / password_reset.html&#39;。
我强烈建议您浏览以下链接 http://garmoncheg.blogspot.com.au/2012/07/django-resetting-passwords-with.html
答案 5 :(得分:0)
在urls.py
path('password-reset/', views.ChangePassword.as_view(), name='password-reset'),
密码更改表格:
class MyPasswordChangeForm(PasswordChangeForm):
def __init__(self, user, *args, **kwargs):
self.user = user
super().__init__(user, *args, **kwargs)
self.fields['old_password'].widget.attrs.update({'class': 'form-control', 'placeholder': "Old Password"})
self.fields['new_password1'].widget.attrs.update({'class': 'form-control', 'placeholder': "New Password"})
self.fields['new_password2'].widget.attrs.update({'class': 'form-control', 'placeholder': "New Password"})
def save(self, commit=True):
password = self.cleaned_data["new_password1"]
self.user.set_password(password)
if commit:
self.user.save()
return self.user
在views.py中:
from django.views.generic import TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin
class ChangePassword(LoginRequiredMixin,TemplateView):
def get(self, request, *args, **kwargs):
form_class = MyPasswordChangeForm
form = self.form_class(self.request.user)
return render(request, 'password.html',{'form': form,})
def post(self, request, *args, **kwargs):
form = self.form_class(request.user, request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user) # Important!
return render(request, 'password.html', {'form': form, 'password_changed': True})
else:
return render(request, 'password.html', {'form': form, 'password_changed': False})
在password.html中:
<div id='PasswordChnageForm'>
<form method="post" action="{% url 'password-reset' %}">
{% csrf_token %}
{% for field in form %}
{{ field }}
{% if field.help_text %}
<small style="display: none">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
{% endfor %}
<input type="submit" name="save" value="Save" >
</form>
</div>
<script src="{% static 'web_admin/js/jquery-3.4.1.min.js' %}"></script>
<script>
$("#CallPasswordChangeButton").on('click', function (e) {
e.preventDefault(); // avoid to execute the actual submit of the form.
var form = $('#PasswordChnageForm');
$.ajax({
type: 'Post',
url: "{% url 'password-reset' %}",
data: form.serialize(),
success: function (data) {
$('#password_change').empty().html(data);
}
});
});
</script>
答案 6 :(得分:0)
实际上你可以使用 Django 表单,它们有一个名为“PasswordChangeForm”的内置表单,你可以从“django.contrib.auth.forms”中导入它
但对我来说,我总是喜欢用静态的 html 表单来做每件事,并通过我的手一步一步地构建我的 views.py 函数。
这是我的例子:
html 表单:
<div class="col-md-6">
<form method="POST">
{% csrf_token %}
<div class="form-group">
<label for="exampleInputPassword1">Old Password</label>
<input type="password" name="q_Old_Password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-group">
<label for="NewPassword">New Password</label>
<input type="password" name="q_new_Password" class="form-control" id="NewPassword" placeholder="Password">
</div>
<div class="form-group">
<label for="ConfirmNewPassword">Confirm New Password</label>
<input type="password" name="q_confirm_new_Password" class="form-control" id="ConfirmNewPassword" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
这里是 views.py 函数:
from django.contrib.auth.models import User
from django.contrib.auth import update_session_auth_hash
def change_password(request):
if request.method == 'POST':
old_password = request.POST.get("q_Old_Password")
new_password = request.POST.get("q_new_Password")
confirmed_new_password = request.POST.get("q_confirm_new_Password")
if old_password and new_password and confirmed_new_password:
if request.user.is_authenticated:
user = User.objects.get(username= request.user.username)
if not user.check_password(old_password):
messages.warning(request, "your old password is not correct!")
else:
if new_password != confirmed_new_password:
messages.warning(request, "your new password not match the confirm password !")
elif len(new_password) < 8 or new_password.lower() == new_password or \
new_password.upper() == new_password or new_password.isalnum() or \
not any(i.isdigit() for i in new_password):
messages.warning(request, "your password is too weak!")
else:
user.set_password(new_password)
user.save()
update_session_auth_hash(request, user)
messages.success(request, "your password has been changed successfuly.!")
return redirect('dashboard_namespace:home')
else:
messages.warning(request, " sorry , all fields are required !")
context = {
}
return render(request, "pages/users_accounts/change_password.html", context)
我希望这有帮助。