• django用户认证系统——登录4


     

     

    用户已经能够在我们的网站注册了,注册就是为了登录,接下来我们为用户提供登录功能。和注册不同的是,Django 已经为我们写好了登录功能的全部代码,我们不必像之前处理注册流程那样费劲了。只需几分钟的简单配置,就可为用户提供登录功能。接下来就来看看如何使用内置的登录功能。

    引入内置的 URL 模型

    Django 内置的登录、修改密码、找回密码等视图函数对应的 URL 模式位于 django.contrib.auth.urls.py 中,首先在工程的 urls.py 文件里包含这些 URL 模式。打开 django_auth_example/ 目录下的 urls.py 文件,将 django.contrib.auth.urls.py 包含进来:

    django_auth_example/urls.py
    
    from django.conf.urls import url, include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^users/', include('users.urls')),
        # 将 auth 应用中的 urls 模块包含进来
        url(r'^users/', include('django.contrib.auth.urls')),
    ]
    

    这将包含以下的 URL 模式:

    ^users/login/$ [name='login']
    ^users/logout/$ [name='logout']
    ^users/password_change/$ [name='password_change']
    ^users/password_change/done/$ [name='password_change_done']
    ^users/password_reset/$ [name='password_reset']
    ^users/password_reset/done/$ [name='password_reset_done']
    ^users/reset/(?P<uidb64>[0-9A-Za-z_-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
    ^users/reset/done/$ [name='password_reset_complete']
    

    设置模板路径

    默认的登录视图函数渲染的是 registration/login.html 模板,因此需要在 templates/ 目录下新建一个 registration 文件夹,再在 registration/ 目录下新建 login.html 模板文件。此时目录结构为:

    django_auth_example/
        manage.py
        django_auth_example/
            __init__.py
            settings.py
            urls.py
            wsgi.py
        templates/
            users/
                register.html
            registration/
                login.html
    

    编写登录模板

    登录模板的代码和注册模板的代码十分类似:

    registration/login.html
    
    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <title>登录</title>
        <link rel="stylesheet" href="https://unpkg.com/mobi.css/dist/mobi.min.css">
        <style>
            .errorlist {
                color: red;
            }
        </style>
    </head>
    <body>
    <div class="flex-center">
        <div class="container">
            <div class="flex-center">
                <div class="unit-1-2 unit-1-on-mobile">
                    <h3>登录</h3>
                    <form class="form" action="{% url 'login' %}" method="post">
                        {% csrf_token %}
                        {{ form.non_field_errors }}
                        {% for field in form %}
                            {{ field.label_tag }}
                            {{ field }}
                            {{ field.errors }}
                            {% if field.help_text %}
                                <p class="help text-small text-muted">{{ field.help_text|safe }}</p>
                            {% endif %}
                        {% endfor %}
                        <button type="submit" class="btn btn-primary btn-block">登录</button>
                    </form>
                    <div class="flex-left top-gap text-small">
                        <div class="unit-2-3"><span>没有账号?<a href="{% url 'users:register' %}">立即注册</a></span></div>
                        <div class="unit-1-3 flex-right"><span><a href="reset_password.html">忘记密码?</a></span></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    </body>
    </html>
    

    为了登录页面的美观我引入了 mobi.css 提供样式支持,其它代码请忽略,我们只关注表单部分的代码。

    <form class="form" action="{% url 'login' %}" method="post">
      {% csrf_token %}
      {{ form.non_field_errors }}
      {% for field in form %}
        {{ field.label_tag }}
        {{ field }}
        {{ field.errors }}
        {% if field.help_text %}
            <p class="help text-small text-muted">{{ field.help_text|safe }}</p>
        {% endif %}
      {% endfor %}
      <button type="submit" class="btn btn-primary btn-block">登录</button>
    </form>
    

    循环表单字段、渲染控件、渲染帮助信息等在注册表单部分已经讲过,登录表单中只引入了一个新的东西:{{ form.non_field_errors }},这显示的同样是表单错误,但是显示的表单错误是和具体的某个表单字段无关的。相对 {{ field.errors }},这个则显示的是具体某个字段的错误。比如对于字段 username,如果用户输入的 username 不符合要求,比如太长了或者太短了,表单会在 username 下方渲染这个错误。但有些表单错误不和任何具体的字段相关,比如用户输入的用户名和密码无法通过验证,这可能是用户输入的用户名不存在,也可能是用户输入的密码错误,因此这个错误信息将通过 {{ form.non_field_errors }} 渲染。

    注意:你可能觉得用户名不存在错误和 username 字段有关,密码错误和 password 字段有关。但是在现代的用户认证系统中,我们不为用户提供这么详细的信息,只是笼统地告知用户名不存在或者密码错误。这能提高一些用户账户的安全性。

    此外登录表单的 action 属性的值是 {% url 'login' %},即 auth 应用下的 login 视图函数对应的 URL,用户提交的表单数据将提交给这个 URL,Django 调用 login 视图函数来处理。

    不要忘了加 {% csrf_token %} 模板标签。

    现在打开开发服务器,在浏览器输入 http://127.0.0.1:8000/users/login/,你将看到一个用户登陆表单。

    用户登陆表单

    故意使用一个不存在的账户登录,或者故意输错密码,你将看到表单渲染的非字段相关的错误。

    登录错误信息

    如果用户登录成功,你会发现跳转到了 http://127.0.0.1:8000/accounts/profile/ 页面。由于我们没有写任何视图函数处理这个 URL,所以看到一个 404 错误。不过没有关系,我们目前只关注用户是否已经登录。

    如何在模板中判断用户是否已经登录

    在模板中判断用户是否已经登录非常简单,使用 {% if user.is_authenticated %} 条件判断即可。借此机会,我们来处理一下网站首页。

    在 user/views.py 写一个首页视图函数:

    user/views.py 
    
    def index(request):
        return render(request, 'index.html')
    

    为这个视图函数配置 URL 模式,在 django_auth_example/urls.py 进行配置:

    from django.conf.urls import url, include
    from django.contrib import admin
    
    from users import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        # 别忘记在顶部引入 include 函数
        url(r'^users/', include('users.urls')),
        url(r'^users/', include('django.contrib.auth.urls')),
        # 别忘记在顶部引入 views 模块
        url(r'^$', views.index, name='index')
    ]
    

    注意:直接在项目的 urls.py 中配置 URL 是不推荐的,应该在应用的 urls.py 下进行配置,然后在项目的 urls.py 中通过 include 函数包含。不过这里作为示例情况特殊,所以姑且这样做。

    由于视图渲染了 index.html 文件,因此在 templates/ 目录下建一个 index.html 模板文件(注意我们没有把它放在 users/ 下,也没放在 registration/ 下)。然后写上下面的代码:

    templates/index.html
    
    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <title>首页</title>
        <link rel="stylesheet" href="https://unpkg.com/mobi.css/dist/mobi.min.css">
    </head>
    <body>
    <div class="flex-center">
        <div class="container">
            <div>
                <h1 class="logo"><a href="{% url 'index' %}">Django Auth Example</a></h1>
                {% if user.is_authenticated %}
                    <p>你已登录,欢迎你:<a href="#">{{ user.username }}</a></p>
                {% else %}
                    <p>你还没有登录,请
                        <button class="btn btn-default"><a href="{% url 'login' %}">登录</a></button>
                        或者
                        <button class="btn btn-default"><a href="{% url 'users:register' %}">注册</a></button>
                    </p>
                {% endif %}
            </div>
        </div>
    </div>
    </body>
    </html>
    

    为了页面的美观,我引入了 mobi.css 提供样式支持。其它代码请忽略,重点只关注用户登录验证部分:

    {% if user.is_authenticated %}
        <p>你已登录,欢迎你:<a href="#">{{ user.username }}</a></p>
    {% else %}
        <p>你还没有登录,请
        <button class="btn btn-default"><a href="{% url 'login' %}">登录</a></button>
        或者
        <button class="btn btn-default"><a href="{% url 'users:register' %}">注册</a></button>
    </p>
    {% endif %}
    

    user.is_authenticated 当用户已经登录时返回 True,否则返回 False。所以已登录的用户将看到欢迎页面,否则将看到登录注册按钮。

    你也许奇怪我们在 index 视图中并没有传递 user 模板变量给 index.html,为什么可以在模板中引用 user 呢?这是因为 Django 的 auth 应用为我们设置了模板常量,所以在任何模板中都可以引用 {{ user }}。此外,我们之前提过的 django.contrib.auth.middleware.AuthenticationMiddleware 为所有的请求 request 绑定了一个 user 属性。所以在模板中引用 {{ user }} 和 {{ request.user }} 是等价。

    OK 了!不过目前为止,如果你已经登录过了,想要看看未登录的效果会变得比较困难,因为我们还无法注销登录。下面就来给网站添加注销登录的功能吧!

  • 相关阅读:
    [ZT]SAP ECC5.0 Working Log TO 2008.5.26
    VS错误:Lc.exe 已退出错误 返回代码 1
    如何实现两个数据库的同步?
    sp_configure 'max server memory'
    [轉]中国油价世界最高 是美国7倍!
    C#WinForm App自动更新(Live Update)架构
    利用批處理自動在異地備份數據庫
    18种根据屏幕字段查找潜在数据的技巧
    [ZT]2008年到校园招聘各企业待遇曝光
    吉祥物由于具有商业气息,所以历届奥运会吉祥物都没有出场。
  • 原文地址:https://www.cnblogs.com/AmilyWilly/p/8469859.html
Copyright © 2020-2023  润新知