额。。。 首先说一下上一篇留的一个坑吧。登录那里我试了一下,貌似root登录不了。看了一下原因,是因为我们的Form中username是EmailField(),这是不对滴,我们需要将其改为CharField()。恩,是这样的。
之后我们看一下今天的问题,找回密码。通过Email来找回密码。这么说来我们之前的Email注册验证是可以复用的喽。
来复用一下。
不过按照我们之前的逻辑,先来看一下html。
- html修改静态文件
这里就不多说了,跟之前一样。
- 配置url
来到users下的urls.py
from .views import ForgetPwdView
urlpatterns = [
...
...
url(r'forgetpwd/', ForgetPwdView.as_view(), name='forget_pwd'),
]
- 配置View
class ForgetPwdView(View):
def get(self, request):
return render(request, 'forgetpwd.html', {
})
def post(self, request):
return render(request, 'forgetpwd.html', {})
这里我们需要使用之前的验证码,我们来处理一下,其实到这里我们只需要直接使用Form来创建一个captcha就ok了。
- Form
来编写我们的Form
class ForgetPwdForm(forms.Form):
email = forms.EmailField()
captcha = CaptchaField()
来更新一下我们的View的get
def get(self, request):
form = ForgetPwdForm()
return render(request, 'forgetpwd.html', {
'form': form,
})
在来更改一下html,html中验证码的位置需要修改。
<div class="form-group captcha1 marb38">
<label>验 证 码</label>
{{ form.captcha }}
</div>
我们来看一下效果。
![](https://img.haomeiwen.com/i1503554/a4837330bc1ef36a.png)
没什么问题。
在修改一个地方,我们发现我们的登录位置有一个叫做忘记密码的<a>,我们来修改一下里面的url。
<a class="fr" href="{% url 'users:forget_pwd' %}">忘记密码?</a>
这样我们在点击忘记密码的时候,就会跳到刚才定义的forget.html了。
格式有点奇怪{% url '' %}.
注意哦,第一%右边有一个空格 第二个%左边有一个空格。
接下来我们来解决一下post请求。
- 修改html
这里主要是添加{% csrf_token %}
然后确认一下,html中input的name跟form中的name是否相同
- 修改view
def post(self, request):
form = ForgetPwdForm(request.POST)
if form.is_valid():
email = request.POST.get('email')
status = send_your_email(email)
if status:
return render(request, 'active_result.html', {
'result': '发送成功',
})
else:
return render(request, 'active_result.html', {
'result': '发送邮件失败',
})
else:
return render(request, 'forgetpwd.html', {
'form': form,
'errors': form.errors
})
接下来我们修改一下我们的send_your_email方法,因为我们需要将forget send email 与 register send email区别开,我们还需要给EmailValidateModel价格字段。
- 修改EmailValidateModel
class EmailValidateModel(models.Model):
add_time = models.DateField(verbose_name=u'添加时间', auto_now=True)
email = models.EmailField(verbose_name=u'邮箱')
validate_code = models.CharField(max_length=20, verbose_name=u'验证码')
#新加send_type类型
send_type = models.CharField(max_length=50, verbose_name=u'类型', choices=(('register', u'注册'), ('forgetpwd', u'忘记密码')), default='register')
class Meta:
verbose_name = u'邮箱验证码信息'
verbose_name_plural = verbose_name
def __unicode__(self):
return self.email
更改一下数据库
makemigrations users
migrate users
修改一下我们的send_your_email函数
def send_your_email(email, send_type='register'):
code = generate_random_str(4)
if send_type == 'register':
email_title = '鲸之网在线注册激活链接'
email_body = '请点击下面的连接激活你的账号: http://127.0.0.1:8000/active/{0}'.format(code)
else:
email_title = '鲸之网在线忘记密码连接'
email_body = '请点击下面的连接修改你的密码: http://127.0.0.1:8000/password_reset/{0}'.format(code)
send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
#如果成功保存到数据库
if send_status:
model = EmailValidateModel()
model.email = email
model.validate_code = code
model.send_type = send_type
model.save()
return send_status
OK,基本都全了,看一下效果。
![](https://img.haomeiwen.com/i1503554/804d704fabaa9bec.png)
收到验证码,没问题,我们再来设置一下修改密码界面就OK了。
老样子,先来修改html文件。
- html
这里就不多说了吧,都是体力活。
- url
这里我们url修改是是在TestProject目录下修改的
url(r'password_reset/(?P<name>.*)', RegisterActiveView.as_view(), name='register_active'),
这里的password_reset是我们邮箱收到的url决定的,同样(?P<name>)中的name也是十分重要的。我们后面的get会用到。
- view
class ForgetActiveView(View):
def get(self, request, code):
return render(request, 'password_reset.html', {})
def post(self, request, code):
return render(request, 'login.html', {})
这里跟上面不同,这里我们的get基本不需要做什么事情,只需要显示界面即可,不需要传值什么的。
关键是post,post我们又需要一个form,来写form
-form
form很简单,需要注意的地方是csrf_token的添加、input name属性与这里的字段要对应。
class PWD_ResetFrom(forms.Form):
password1 = forms.CharField(min_length=8)
password2 = forms.CharField(min_length=8)
- 修改view
def post(self, request, code):
form = PWD_ResetFrom(request.POST)
if form.is_valid():
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
if password1 == password2:
validate_model = EmailValidateModel.objects.get(validate_code=code, send_type='forgetpwd')
try:
user = UserProfile.objects.get(email=validate_model.email)
user.password = make_password(password1)
user.save()
except:
print('查询错误')
return render(request, 'login.html', {})
else:
return render(request, 'password_reset.html', {
'msg': '两次输入的密码不同'
})
else:
return render(request, 'password_reset.html', {
'errors': form.errors
})
这里还有一个地方需要注意的就是在修改密码的时候需要使用make_password来对密码进行加密然后在保存。
之前跟群里朋友研究bug的时候,他说他数据库有密码,但是登录不了,后来发现,是他在添加的时候并没有对密码进行加密,然而我们在使用login的时候,django会自动对我们的密码进行加密然后在与数据库中的password作比较。所以如果忘记加密的同学小心登录不了哦。
恩,这样我们就找回密码了。
强势分割线
有登录没有登出总不行吧。我们来搞一下呗。
这里我们可以去到首页
- en 还是html
不解释
- url
这里我们来到users.url.py中搞一下。
from .views import LoginView, RegisterView, ForgetPwdView, LogoutView
urlpatterns = [
...
url(r'logout/', LogoutView.as_view(), name='logout')
]
- view
这里呢,我们需添加一个头文件,没错就是logout
from django.contrib.auth import logout
然后呢我们只需要调用
logout(request)
接下来呢,是一个比较重要的地方,就是关于重定向问题。
我们知道render本质是一个Response,这里我们需要用到HttpResponseRedirect, reverse
引入头文件
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
然后开始return我们的重定向response
return HttpResponseRedirect(reverse('index'))
看一下是否退出了呢?
我们来加个断点看一下。
![](https://img.haomeiwen.com/i1503554/7d218b20a35b25dd.png)
![](https://img.haomeiwen.com/i1503554/876e8685ffe56f88.png)
我们可以看到,在登录情况下,我们的request.user属性是有值得。
退出看一下。
![](https://img.haomeiwen.com/i1503554/15ba47555f10b630.png)
这时,我们的request。user就没有值了
![](https://img.haomeiwen.com/i1503554/aee194b775d04904.png)
退出成功。
这里刚遇到一个坑,比如我想跳转到login界面怎么弄呢?
注意login是include里的url
我一开始直接写的login,这个login是怎么来的呢,在这里。
![](https://img.haomeiwen.com/i1503554/5785c85c7efee5dd.png)
但是我发现不行,于是我就尝试是不是要用 users/login,很不幸,并没有成功。查资料看到了这篇文章
想到要不要换成users.login,发现还是不行。但是还好在文章中看到了这样一句话。
![](https://img.haomeiwen.com/i1503554/81a27b471c7083b4.png)
我们在模板中的使用是这样的。
![](https://img.haomeiwen.com/i1503554/2054ebddaad96486.png)
网友评论