龙空技术网

Django搭建网络相册:登录与登出

杜赛 186

前言:

当前各位老铁们对“css相册代码”大概比较讲究,我们都想要知道一些“css相册代码”的相关文章。那么小编也在网摘上汇集了一些对于“css相册代码””的相关内容,希望同学们能喜欢,同学们快快来了解一下吧!

作为个人相册来说,通常只需要简单的用户管理就足够了,原因如下:

具有操作资源权限的只有自己,不用考虑诸多网络安全的问题。Django 后台提供了丰富的管理能力。评论等需要登录参与的功能可以托管给第三方。(比如 Github 的某些评论插件)

话虽如此,但前台登录退出功能还是要有的,后台总归没那么直观。

因此本章就来简单实现下管理员账户在前台的登入和登出。

后端代码

浏览器发起的 HTTP 请求,总共定义了八种请求类型,来表示对指定资源的不同操作方式。比如说前面章节在访问相册主页时,实际上提起的是 GET 请求。GET 请求被称为安全请求,因为按照规范,它不应该在服务器上产生任何结果,也就是不会修改信息。

安全方法也被称作是幂等的

其他常用的还有 POST 请求,它的使用又分两种情况。

一种情况是 POST 请求会修改服务器资源,比如发表新文章、修改用户数据等,另一种情况是请求会携带敏感信息。用户的登入登出就属于第二种情况。

GET 请求会将信息暴露在地址栏中,且更容易受到跨域等攻击。

因此首页的 home() 视图函数不仅要处理显示图片的 GET 请求,还要肩负用户登录管理的 POST 请求。

像这样修改 views.py 文件:

# /photo/views.pyfrom django.shortcuts import renderfrom photo.models import Photofrom django.contrib.auth import authenticate, login, logoutdef home(request):    photos = Photo.objects.all()    context = {'photos': photos}    # 处理登入登出的POST请求    if request.method == 'POST':        username = request.POST.get('username')        password = request.POST.get('password')        user     = authenticate(request, username=username, password=password)        # 登入        if user is not None and user.is_superuser:            login(request, user)        # 登出        isLogout  = request.POST.get('isLogout')        if isLogout == 'True':            logout(request)    return render(request, 'photo/list.html', context)
请求体 request 包含用户请求的相关信息。request.method 即表明了请求的类型。如果是登录相关的 POST 请求,那么进行下一步的处理。request.POST.get() 可获取到 POST 请求中包含的数据。这里就是用户名和密码了。验证用户名、密码是否正确要用 authenticate() 方法。切记不能直接去比较模型中的字符串,因为密码是加密存储的。如果此用户存在并且是管理员,那么则 login() 函数登入。否则不进行处理。请求中还包含一个标志位 isLogout 用来判断用户是想登入还是登出。如果它为真,则 logout() 退出账号。

除此之外其他还是和之前一样了。

接下来是前端部分。

前端代码

登录功能一般会将入口放在页眉上,这样可以保证用户可以在任意网页位置进行登入登出操作。

因此修改 header.html 模板文件,变成下面这样:

<!-- /templates/header.html --><!-- 导航栏 --><nav class="navbar navbar-expand navbar-dark bg-dark">    <div class="container">        <!-- 标志 -->        <a             class="navbar-brand"             href="#"            data-bs-toggle="modal"             data-bs-target="#login"        >            <h2>                Awesome Album            </h2>        </a>        <!-- 登录模态窗 -->        {% if user.is_superuser %}            <ul class="navbar-nav">                <li class="nav-item">                <h2>                    <a class="nav-link active" aria-current="page" href="#">                        +                    </a>                </h2>                </li>            </ul>        {% endif %}    </div></nav><!-- 登出 -->{% if user.is_superuser %}<div class="modal fade" id="login">    <div class="modal-dialog">        <div class="modal-content">            <div class="modal-body">                <p>确认退出账号吗?</p>                <form action="{% url 'home' %}" method="post">{% csrf_token %}                    <input type="text" id="isLogout" name="isLogout" value="True" hidden>                    <button type="submit" class="btn btn-danger">Logout</button>                </form>            </div>        </div>    </div></div><!-- 登录 -->{% else %}<div class="modal fade" id="login">    <div class="modal-dialog">        <div class="modal-content">            <div class="modal-body">                <form action="{% url 'home' %}" method="post">{% csrf_token %}                    <div class="mb-3">                        <label for="username" class="form-label">Username</label>                        <input type="text" class="form-control" id="username" name="username">                    </div>                    <div class="mb-3">                        <label for="pwd" class="form-label">Password</label>                        <input type="password" class="form-control" id="pwd" name="password">                        <div id="passwordHelp" class="form-text">                            We'll never share your password with anyone else.                        </div>                    </div>                    <button type="submit" class="btn btn-primary">Login</button>                </form>            </div>        </div>    </div></div>{% endif %}

主要变化就是将导航栏里的网站标题变成了模态窗的入口。页面会根据用户的登录与否,决定显示登入还是登出的模态窗,并同时显示或隐藏“创建新相片”的按钮。

需要注意的点:

{% if user.is_superuser %} 判断当前是否是管理员用户,与视图中的 user.is_superuser 是相同的。在模板中要包裹在标签内。根据是否是管理员用户,模态窗的具体内容有所不同。这个内容就决定了用户是要登入还是登出。表单元素 <form ...> 中的 action="{% url 'home' %}" 说明此表单提交给当前页面。注意这里的 'home' ,就是当初我们在 path() 中给 url 赋予的名字。method="post" 说明表单提交的是 POST 请求。登出的模态窗有一个 <input ... hidden> 的隐藏数据,此数据不显示给用户,但是会悄悄提交 isLogout="True" 这个数据。就是靠它来确定登入登出状态的。注意每个表单都有 {% csrf_token %} 这么个东西,这是 Django 用来防止跨域攻击的小插件,默认情况下表单必须携带,否则会报 403 错误。

接下来测试。

测试

刷新页面,点击页眉中的标题:

提示登录的模态窗就显示出来了。

输入管理员账号密码后,点击提交按钮,有如下变化:

注意看页眉右边出现个加号,这就表示登录成功了。

这个加号用于后续章节上传图片。目前暂时没有功能。

再次点击页眉标题,此时显示的就是提示退出登录的模态窗了。点击红色的提交按钮后,应该就正常退出了账户,右侧的小加号也消失了。

总结

本章学习了 Django 中如何处理用户的登录问题的。

你会发现后端的 Python 代码总是比前端 html 代码更少,很大一部分原因是 Django 很好的封装了通用的功能。用户验证就是个例子,你可以在后台中看看用户密码,它是以密文的形式存储的。但是你的代码中完全没管加密与解密的问题,直接调用内置的 authenticate() 函数就搞定了。

登入登出功能也一样,Django 封装了具体的处理方式,你调用 login()logout() 函数即可。

另一方面,你真的不用害怕大量的 html 代码。教程中涉及的内容大概就和 Word 文档排版的难度差不多,唯一区别就是 Word 排版是用鼠标点点点,而 html 将点点点的动作转化成了英文字母。多查阅一定看得懂。

下一章聊聊如何批量上传图片。

点赞 or 吐槽?评论区告诉我!

标签: #css相册代码