Python 如何在Django 1.9中实现密码更改表单
我的python项目的url如下:Python 如何在Django 1.9中实现密码更改表单,python,django,django-users,Python,Django,Django Users,我的python项目的url如下: 我正在尝试实现密码更改表单,以便用户可以更改其密码。我如何实现它?应用程序应跟踪以前的密码,并且不应允许用户使用以前使用的密码。另外,我想实现重置密码功能 您可以查看以下文档中的更改密码部分。 它的工作原理如下: 导航到位于manage.py文件的项目 $python manage.py shell 执行以下操作: from django.contrib.auth.models import User u = User.objects.get(usernam
我正在尝试实现密码更改表单,以便用户可以更改其密码。我如何实现它?应用程序应跟踪以前的密码,并且不应允许用户使用以前使用的密码。另外,我想实现重置密码功能 您可以查看以下文档中的更改密码部分。 它的工作原理如下:
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*用户名*
只需输入两次新密码
对于问题的第二部分(用户不能选择旧密码),您可以创建一个表,在其中存储用户的旧密码。当用户输入新密码时,您可以在该表中检查该密码,无论他是否可以选择该密码。Django有一个用于比较两个密码的函数。如果您查看
您会注意到,password\u reset采用了一个名为template\u name的命名参数
因此,使用类似URL.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\u reset将为匹配'/accounts/password/reset'的URL调用,其关键字参数为template\u name='my\u templates/password\u reset.html'。
我强烈建议您浏览以下链接
由于您使用的是自定义用户模型,因此实现该功能的一个好方法是创建一个新表单
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()
来检查两个密码是否匹配,以及输入的新密码是否与旧密码不同
如果您不想让用户使用他们在启用选项之前使用过的密码
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..
代码只是帮助你理解你需要做什么,你必须用自己的方式去做 为什么不使用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': 'Το συνθηματικό δε μπορεί να είναι κενό'})
稍后我将提供一个clean和save方法的示例
有关更多详细信息,请参见
from django.contrib.auth.forms import PasswordChangeForm
然后
在你看来
def get(self,request):
实例\用户=获取\对象\或\ 404(用户,id=int(用户\ id))
表单\编辑\密码=MyChangeFormPassword(实例\用户)
上下文={'form_edit_password':form_edit_password}
返回渲染(请求、self.template\u名称、上下文)
在模板上
{{form_edit_password.old_password}}
{{form_edit_password.new_password1}}
{{form_edit_password.new_password2}}
你的职位呢
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写这篇文章的。在url.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>
{%csrf_令牌%}
{%形式的字段为%}
{{field}}
{%if field.help_text%}
{{field.help_text}
{%endif%}
{%字段中有错误。错误%}
{{error}
{%endfor%}
{%endfor%}
$(“#CallPasswordChangeButton”)。在('click',函数(e){
e、 preventDefault();//避免执行表单的实际提交。
var form=$(“#PasswordChnageForm”);
$.ajax({
键入:“Post”,
url:“{%url'密码重置“%}”,
数据:form.serialize(),
成功:功能(数据){
$('#密码_更改').empty().html(数据);
}
});
});
So template\u name-应该是我重置密码的自定义模板吗?您提供的链接是否足以使用示例模板?您是指旧的\u password=forms.PasswordInput()?因为我的无法解决你的问题,“用户”在这里是什么意思?我需要创建一个单独的类来存储用户吗?另外,“return self.cleaned_data”给了我“return out of function”是的,它是forms.PasswordInput(),用户对象意味着你的成员的类对象,return应该可以很好地工作。试着从这里读取这似乎并不能回答问题。OP希望有一个更改密码表单(和视图/模板),以及密码历史记录。@GregSchmit在我看来,他询问的功能的答案将非常长。这就是为什么我没有写完整的代码。相反,我写了他如何解决他的问题。我同意这是一个宽泛的、不恰当的问题。
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})
<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>