Django1.6 用Form实现注册登录注销修改密码(含代码!)

本文详细介绍了如何使用Django框架实现用户登录与注册功能,包括搭建项目环境、编写URL配置、设计表单验证、实现视图逻辑等步骤。

参照了潘军杰的博客,但他Django版本有点老了,改动了不少东西,总体来说参考价值还是很大的,点http://www.2goo.info/blog/panjj/Django/2010/06/05/94跳转

按上Django的可以去目录下找auth这个包,它涵盖了登录注册的大部分功能,我们拿过来直接用就可以了。我Python按在了D盘,所以目录就是这个,D:\Python2.7.6\Lib\site-packages\django\contrib\auth。不会用某个函数看一下这里面或者去看官方文档帮助都很大。最后我会提供工程压缩包,有兴趣的可以下载。

点击此处下载程序包

1.先建立自己的项目,推荐大家使用eclipse+pydev+django的组合,比我之前一直用的cmd方便太多了!首先说一下我的目录结构,如图


MyLogin是创建项目的时候自动创建的,同级的还有manage.py。我自己创建了login文件夹存放登录的views和form,templates文件夹存放模板。tests、models那些都是自动生成的,这次并没有用到。

切记在settings.py里设置自己的模板目录!如果你下载压缩包一定要改这里,而且不能直接复制地址栏的目录,要把'\'全部换成‘/’!!!

2.也是从urls入手,其实只需要一个注册界面和一个登陆界面,所以代码如下

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. from django.conf.urls import patterns, include, url  
  2. from django.contrib import admin  
  3. from login.views import register,mylogin,changepassword  
  4. admin.autodiscover()  
  5.   
  6. urlpatterns = patterns('',  
  7.     url(https://blog.csdn.net/r%3Cspan%20class=%22string%22%20style=%22margin:0px;%20padding:0px;%20border:none;%20color:blue;%20background-color:inherit%22%3E'^admin/'%3C/span%3E%3Cspan%20style=%22margin:0px;%20padding:0px;%20border:none;%20background-color:inherit%22%3E,%C2%A0include(admin.site.urls)),  
  8.     (r'^register/$',register),  
  9.     (r'^login/$',mylogin),  
  10.     (r'^login/register/$',register),  
  11.     (r'^changepassword/(?P<username>\w+)/$',changepassword),  
  12. )  

第一行是自动生成的,第二、三行是开始就添加的,第四、五行是后续增添功能时另加的。

3.接下来编写form表单,新建一个py文件命名为form。

注册的时候我们要求用户填用户名、邮箱、还要输入两次密码,所以我们的RegisterForm就诞生了。

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. from django import forms  
  2. class RegisterForm(forms.Form):  
  3.     username = forms.CharField()  
  4.     email = forms.EmailField()  
  5.     password = forms.CharField(widget=forms.PasswordInput)  
  6.     password2= forms.CharField(label='Confirm',widget=forms.PasswordInput)  
  7.     def pwd_validate(self,p1,p2):  
  8.         return p1==p2  

需要说明的是widget那个是为了让输入内容不显示出来,而且django会把密码转存成一个哈希串,label是在页面显示的内容。那个函数是为了判断两次密码输入是否相同,其实不写这里写到views里也可以。

同样登录界面只需要用户名和密码即可,所以LoginForm更简单

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class LoginForm(forms.Form):  
  2.     username = forms.CharField()  
  3.     password = forms.CharField(widget=forms.PasswordInput)  

4.接下来开始编写views。首先介绍需要导入的包

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. from django.shortcuts import render_to_response  
  2. from form import RegisterForm,LoginForm,ChangepwdForm  
  3. from django.contrib.auth import authenticate,login as auth_login,logout as auth_logout  
  4. from django.http import HttpResponsefrom django.http import HttpResponseRedirect  

User的位置发生了变化,我找了很久才找到的。导入login,logout时为了区分所以加了auth前缀
5.简单起见先写login视图

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. def mylogin(request):  
  2.     error = []  
  3.     if request.method == 'POST':  
  4.         form = LoginForm(request.POST)  
  5.         if form.is_valid():  
  6.             data = form.cleaned_data  
  7.             username = data['username']  
  8.             password = data['password']  
  9.             if login_validate(request,username,password):  
  10.                 return render_to_response('welcome.html',{'user':username})  
  11.             else:  
  12.                 error.append('Please input the correct password')  
  13.         else:  
  14.             error.append('Please input both username and password')  
  15.     else:  
  16.         form = LoginForm()  
  17.     return render_to_response('login.html',{'error':error,'form':form})  

其中login_validate()如下

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. def login_validate(request,username,password):  
  2.     rtvalue = False  
  3.     user = authenticate(username=username,password=password)  
  4.     if user is not None:  
  5.         if user.is_active:  
  6.             auth_login(request,user)  
  7.             return True  
  8.     return rtvalue  

为了验证用户合法性,用到了authenticate函数,参数是username和password,匹配到会返回一个User对象,如果不合法(不存在该用户或密码不正确)就会返回None。login.html是自己编写的模板,其中有两个要填充的变量error和form,它会返回这两个变量到模板中来显示具体出现了什么错误。模板有一个地方要注意就是它有两个按钮,Login按钮类型设为submit,一点击就提交;而Register按钮设为button,然后其上加一个点击函数,让其点击后跳转到注册页面。window.location.href是让其在当前页面进行跳转,也就是url变成了/login/register/。这也就是在最开始urls里那么写第四行的原因。login.html内容如下:

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <html>  
  2. <head>  
  3.     <title>Login</title>  
  4.     <script type="text/javascript">  
  5.      
  6.     function register() {  
  7.         window.location.href = 'register'  
  8.     }  
  9. </script>  
  10. </head>  
  11. <body>  
  12.     <h1>Login</h1>  
  13.     {% for item in error %}  
  14.         <p style="color:red;">{{item}}</p>  
  15.     {% endfor %}  
  16.               
  17.     <form action="" method="post">  
  18.         <table>  
  19.             {{ form.as_table }}  
  20.         </table>  
  21.           
  22.         <input type="submit" value="Login">  
  23.         <input type="button" value="Register" onclick="register()">  
  24.     </form>  
  25. </body>  
  26. </html>  

6.有了login再写register就容易了。它要验证的内容稍微多一些,一个是验证要注册的用户名是否已存在,因为username是要唯一的,在一个验证密码是否相同,这个在Form表单里已经写过函数了。

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. def register(request):  
  2.     error=[]  
  3.     if request.method == 'POST':  
  4.         form = RegisterForm(request.POST)  
  5.         if form.is_valid():  
  6.             data = form.cleaned_data  
  7.             username = data['username']  
  8.             email = data['email']  
  9.             password = data['password']  
  10.             password2= data['password2']  
  11.             if not User.objects.all().filter(username=username):  
  12.                 if form.pwd_validate(password, password2):  
  13.                     user = User.objects.create_user(username, email, password)  
  14.                     user.save()  
  15.                     login_validate(request,username,password)  
  16.                     return render_to_response('welcome.html',{'user':username})  
  17.                 else:  
  18.                     error.append('Please input the same password')  
  19.             else:  
  20.                 error.append('The username has existed,please change your username')  
  21.     else:  
  22.         form = RegisterForm()      
  23.     return render_to_response('register.html',{'form':form,'error':error})  

如果可以注册,利用create_user函数来创建一个user对象,然后切记user.save()存入数据库。register.html如下

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <html>  
  2. <head>  
  3.     <title>Join us</title>  
  4. </head>  
  5. <body>  
  6.     <h1>Register</h1>  
  7.   
  8.     {% if form.errors %}  
  9.         <p style="color: red;">  
  10.             Please correct the error{{ form.errors|pluralize }} below.  
  11.         </p>  
  12.     {% endif %}  
  13.     {% for item in error %}  
  14.         <p style="color:red;">{{item}}</p>  
  15.     {% endfor %}  
  16.               
  17.     <form action="" method="post">  
  18.         <table>  
  19.             {{ form.as_table }}  
  20.         </table>  
  21.         <input type="submit" value="Register">  
  22.     </form>  
  23. </body>  
  24. </html>  

7.最后是注销,这个很简单,直接用auth_logout(request)即可,然后返回login界面

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. def mylogout(request):  
  2.     auth_logout(request)  
  3.     return HttpResponseRedirect('/login/')  

8.在注销界面我添加了一个修改密码的选项,让用户登录后可以修改自己的密码,这个主要用到了user.set_password('new password')。唯一复杂的地方是点击修改密码按钮时要多传递过来一个username的参数,这样才能去查找这个user从而修改其密码。所以在urls地方那么写,为了将url里的内容匹配到username变量中,传递给changepassword函数

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. def changepassword(request,username):  
  2.     error = []  
  3.     if request.method == 'POST':  
  4.         form = ChangepwdForm(request.POST)  
  5.         if form.is_valid():  
  6.             data = form.cleaned_data  
  7.             user = authenticate(username=username,password=data['old_pwd'])  
  8.             if user is not None:  
  9.                 if data['new_pwd']==data['new_pwd2']:  
  10.                     newuser = User.objects.get(username__exact=username)  
  11.                     newuser.set_password(data['new_pwd'])  
  12.                     newuser.save()  
  13.                     return HttpResponseRedirect('/login/')  
  14.                 else:  
  15.                     error.append('Please input the same password')  
  16.             else:  
  17.                 error.append('Please correct the old password')  
  18.         else:  
  19.             error.append('Please input the required domain')  
  20.     else:  
  21.         form = ChangepwdForm()  
  22.     return render_to_response('changepassword.html',{'form':form,'error':error})  

如果还不清楚,可以看下我的welcome.html,应该就会清楚参数是如何传递的了

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <html>  
  2. <head>  
  3.     <title>Welcome </title>  
  4. </head>  
  5. <body>  
  6.     <h1>Welcome {{user}}!</h1>  
  7.     <div>  
  8.      <a href="/changepassword/{{user}}">ChangePassword</a>   
  9.      <a href="/login">Logout</a>   
  10.     </div>  
  11.       
  12.       
  13. </body>  
  14. </html>  

点击changepassword后,将user这个变量附加到url上传递过去,所以在urls里那个格式就是负责解析这个url的。w+是正则表达式,意思是一个或多个字符。最后是changepassword.html文件,和其它的模板都差不多

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <html>  
  2. <head>  
  3.     <title>ChangePassword</title>  
  4.      
  5. </head>  
  6. <body>  
  7.     <h1>ChangePassword</h1>  
  8.     {% for item in error %}  
  9.         <p style="color:red;">{{item}}</p>  
  10.     {% endfor %}  
  11.               
  12.     <form action="" method="post">  
  13.         <table>  
  14.             {{ form.as_table }}  
  15.         </table>  
  16.           
  17.         <input type="submit" value="Enter">  
  18.     </form>  
  19. </body>  
  20. </html>  

注意:如果数据库报错,很有可能是你没有同步数据库,运行manage.py syncdb指令同步数据库。可登录http://127.0.0.1:8000/admin登录管理界面
管理员账号:administrator/symantec

有问题欢迎留言讨论交流,转载请注明出处:http://blog.csdn.net/monkeyduck

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值