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

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

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

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


第一部分 注册功能

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

@csrf_protect
def 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_protect
def 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形式为:

iduser_idpermisson_id
11030
21628
xxxxx

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

idnamecontent_type_idcodename
1Can add log entry1add_logentry
2Can change log entry1change_logentry
3Can delete log entry1delete_logentry
4Can add permission2add_permission
5Can change permission2change_permission
6Can delete permission2delete_permission
7Can add group3add_group
8Can change group3change_group
9Can delete group3delete_group
10Can add user4add_user
11Can change user4change_user
xxxxxxxxxxxx
30teacher4is_teacher
31student4is_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框架也会在后面章节中进行说明。

转载于:https://www.cnblogs.com/rfhs/p/6852898.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值