06.中间件的应用.md 2.7 KB

中间件的应用

我们继续来完善投票应用。在上一个章节中,我们在用户登录成功后通过session保留了用户信息,接下来我们可以应用做一些调整,要求在为老师投票时必须要先登录,登录过的用户可以投票,否则就将用户引导到登录页面,为此我们可以这样修改视图函数。

def praise_or_criticize(request: HttpRequest):
    """投票"""
    if 'user' in request.session:
        try:
            tno = int(request.GET.get('tno', '0'))
            teacher = Teacher.objects.get(no=tno)
            if request.path.startswith('/vote/praise'):
                teacher.good_count += 1
            else:
                teacher.bad_count += 1
            teacher.save()
            data = {'code': 200, 'message': '操作成功'}
        except (ValueError, Teacher.DoesNotExist):
            data = {'code': 404, 'message': '操作失败'}
    else:
        data = {'code': 401, 'message': '请先登录'}
    return JsonResponse(data)

前端页面在收到{'code': 401, 'message': '请先登录'}后,可以将用户引导到登录页面。

<script>
    $(() => {
        $('.comment > a').on('click', (evt) => {
            evt.preventDefault()
            let a = $(evt.target)
            $.ajax({
                url: a.attr('href'),
                type: 'get',
                dataType: 'json',
                success: (json) => {
                    if (json.code == 200) {
                        let span = a.next()
                        span.text(parseInt(span.text()) + 1)
                    } else if (json.code == 401) {
                        location.href = '/vote/login/?backurl=' + location.href
                    } else {
                        alert(json.message)
                    }
                }
            })
        })
    })
</script>

注意:为了在登录成功之后能够回到刚才投票的页面,我们在跳转登录时设置了一个backurl参数,把当前浏览器中的URL作为返回的页面地址。

这样我们已经实现了用户必须登录才能投票的限制,但是一个新的问题来了。如果我们的应用中有很多功能都需要用户先登录才能执行,那么我们是不是需要在每个视图函数中添加代码来检查session中是否包含了登录用户的信息呢?答案是否定的,如果这样做了,我们的视图函数中必然会充斥着大量的重复代码。编程大师Martin Fowler曾经说过:代码有很多种坏味道,重复是最坏的一种。我们可以把验证用户是否登录这样的代码放到Django的中间件中。

Django中间件概述

自定义中间件