[Django]SE项目回忆录(二)-注册/登录功能的实现及细节

来源:互联网 发布:mac安装win10激活工具 编辑:程序博客网 时间:2024/05/22 06:49

该项目中提供了注册和登录两部分功能,功能描述如下:

注册:
允许任何用户进行学生身份的注册。
教师用户预先已经保存在数据库中,不允许以游客身份注册新的教师用户。
注册时需要填写的信息包括:
- 用户名
- 密码(确认密码)
- 邮箱

登录:
允许教师和学生两类用户组中的用户进行登录。
登录时需要填写的信息包括:
- 用户名
- 密码
登录成功后,根据不同用户所属的用户组,进入相应的页面。


第一部分 注册功能

首先贴上注册部分的views代码片:

@csrf_protectdef student_register(request):      errors= []      account=None      password=None      password2=None      email=None      CompareFlag=False      if request.method == 'POST':          if not request.POST.get('account'):              errors.append('Please Enter account')          else:              account = request.POST.get('account')          if not request.POST.get('password'):              errors.append('Please Enter password')          else:              password = request.POST.get('password')        if not request.POST.get('password2'):              errors.append('Please Enter password2')          else:              password2 = request.POST.get('password2')          if not request.POST.get('email'):              errors.append('Please Enter email')          else:              email = request.POST.get('email')        if password is not None and password2 is not None:              if password == password2:                  CompareFlag = True              else :                  errors.append('password2 is diff password ')      if account is not None and password is not None and password2 is not None and email is not None and CompareFlag :          if User.objects.filter(username=account):            errors.append('this account already exists, Please change another username')        else:            user=User.objects.create_user(account,email,password)             user.is_active=True            permission=Permission.objects.get(name='student')            user.user_permissions.add(permission)            user.save()            return HttpResponseRedirect('../../')    return render_to_response('account/register.html', {'errors': errors}, context_instance=RequestContext(request))  

水平不足,代码十分简陋,此处只对当时感到困惑的一些问题进行说明了。

Q1:如何返回带有form(表单)的页面

根据Django框架的设定,访问某url时,首先调用views中对应函数,根据函数返回值传回相应contexthtml。大多数使用form元素时,是为了使用post/get的方法向网站传回表单中的数据。但是在初次访问该页面时,没有表单提交的请求,所以在views中的处理函数中如果直接写处理表单数据的代码,系统会报错,因为函数无法从get请求中获取到所需的数据进行相应的操作。
会发生这个问题的原因是对网站逻辑了解模糊,敲代码时关注了提交表单后的数据处理,却忽略了首次访问时如何进入界面的问题。
解决办法是:

views函数中对数据进行处理前先进行逻辑判断,“请求头里面是否有该数据”,没有的话返回原页面,并且提示相应信息。

代码实现:

if request.method == 'POST':      if not request.POST.get('account'):          errors.append('Please Enter account')      else:          account = request.POST.get('account')      if not request.POST.get('password'):          errors.append('Please Enter password')      else:          password = request.POST.get('password')    if not request.POST.get('password2'):          errors.append('Please Enter password2')      else:          password2 = request.POST.get('password2')      if not request.POST.get('email'):          errors.append('Please Enter email')      else:          email = request.POST.get('email')    if password is not None and password2 is not None:          if password == password2:              CompareFlag = True          else :              errors.append('password2 is diff password ')  return render_to_response('account/register.html', {'errors': errors}, context_instance=RequestContext(request))

第二部分 登陆功能

登录部分代码片:

@csrf_protectdef alogin(request):    errors=[]    account=None    password=None    if request.user.is_authenticated():        if request.user.has_perm('auth.is_teacher'):            return HttpResponseRedirect('/update')        else:            return HttpResponseRedirect('/main')    else:        if request.method == 'POST':            if not request.POST.get('account'):                errors.append('Please Enter account')            else:                account = request.POST.get('account')            if not request.POST.get('password'):                errors.append('Please Enter password')            else:                password = request.POST.get('password')            if account is not None and password is not None:                user = authenticate(username=account,password=password)                if user is not None:                    if user.is_active :                        login(request,user)                        if user.has_perm('auth.is_teacher') :                            return HttpResponseRedirect('/update')                        else:                            return HttpResponseRedirect('/main')                    else:                        errors.append('disabled account')                else:                    errors.append('invalid user')        return render_to_response('account/login.html',{'errors':errors}, context_instance=RequestContext(request))

Q1:用户权限管理

如上所述,用户分为教师和学生。用来区分学生和教师的方法是分别赋予两类user的user_permissions不同的值。
user_permissions也是Django框架中内置的一类模型,用于管理一个user所具有的权限。auth_user_user_permissions(即user_permission在Django框架中的名字)的table形式为:

id user_id permisson_id 1 10 30 2 16 28 x xx xx

id表示user_permission的id,user_id和permission_id即代表某个user以及该user所对应的permission有哪些,此处的permission_id为数组形式。
permission_id对应的permission又存储在auth_permission这个table中,其内容大致为:

id name content_type_id codename 1 Can add log entry 1 add_logentry 2 Can change log entry 1 change_logentry 3 Can delete log entry 1 delete_logentry 4 Can add permission 2 add_permission 5 Can change permission 2 change_permission 6 Can delete permission 2 delete_permission 7 Can add group 3 add_group 8 Can change group 3 change_group 9 Can delete group 3 delete_group 10 Can add user 4 add_user 11 Can change user 4 change_user x xxxx xxxx xxx 30 teacher 4 is_teacher 31 student 4 is_student

可以观察到除了30、31行比较特殊外,其余内容比较相似。是因为其他部分都是Django内部自动为每个model生成的,其中包括了内置的如user、group等。
而teacher、student两个则是此项目中手工添加的权限,可以看到,此处teacher和student两个权限的id分别为30和31,对应着前一个表格中的permission_id一列。
以上为实现权限管理功能所做的准备,以及相关数据的说明。接下来简单说一下代码部分是如何实现这个功能的。
在登录函数中,权限判断的代码如下:

if request.user.is_authenticated():    if request.user.has_perm('auth.is_teacher'):        return HttpResponseRedirect('/update')    else:        return HttpResponseRedirect('/main')

user.has_perm('xx')是user的方法之一,用来检查user.user_permission中是否有权限“xxx”存在,此处“xxx”是permission的codename(详见上面表格)。

Q2:用户认证

用户认证的部分代码如下:

if account is not None and password is not None:    user = authenticate(username=account,password=password)    if user is not None:        if user.is_active :            login(request,user)            if user.has_perm('auth.is_teacher') :                return HttpResponseRedirect('/update')            else:                return HttpResponseRedirect('/main')        else:            errors.append('disabled account')    else:        errors.append('invalid user')

其中值得我们关注的部分有:
authenticate(username,password)
user.is_active
login(request,user)
1.authenticate(username,password):该函数接受两个参数usernamepassword,如果该用户名和密码匹配,则返回该user对象;如果不匹配,则返回 None值。
2.user.is_active:是否允许用户登录, 设置为False,可以不用删除用户来禁止用户登录.
3.login(request,user):该函数接受一个HttpRequest 对象和一个 User 对象作为参数并使用Django的会话( session)框架把用户的ID保存在该会话中.

Ps:关于Django的Session框架会在后面的部分单独介绍。
Pps:csrf_protect机制及csrf框架也会在后面章节中进行说明。

0 0
原创粉丝点击