Django Web应用程序(五)

19.2 创建用户账户

这一节,我们将简历一个用户注册和身份验证系统,让用户能够注册账户,进而登录和注销。我们将创建一个新的应用程序,其中包含与处理用户账户相关的所有功能。我们还将对模型Topic稍作修改,让每个主题都归属于特定用户。

19.2.1 应用程序users

我们首先使用命令startapp来创建一个名为users的应用程序

ll_env) c5220056@GMPTIC:~/myworkplace$ python manage.py startapp users
(ll_env) c5220056@GMPTIC:~/myworkplace$ ls
db.sqlite3  learning_log  learning_logs  ll_env  manage.py  users
(ll_env) c5220056@GMPTIC:~/myworkplace$ ls users/
admin.py  apps.py  __init__.py  migrations  models.py  tests.py  views.py

1. 将应用程序users添加到settings.py中
在settings.py中,我们将这个新的应用程序添加到INSTALLED_APPS中

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    # my app
    'learning_logs',
    'users',
]

2. 包含应用程序users的URL
接下来,我们需要修改项目根目录中的urls.py,使其包含我们将为应用程序users定义的URL

from django.contrib import admin
from django.urls import path
from django.conf.urls import include,url

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^users/', include('users.urls', namespace='users')),
    url(r'', include('learning_logs.urls', namespace='learning_logs')),
]

我们添加了一行代码,以包含应用程序users中的文件urls.py。这行代码与任何以users打头的URL(如http://localhost:8000/users/login/)都匹配。我们还创建了命名空间'users',以便将应用程序learning_logs的URL同应用程序users的URL区分开。

19.2.2 登录页面

首先来实现登录页面的功能。为此,我们将使用Django提供的默认登录视图,因此URL模式会稍有不同。在目录learning_log/users中,新建一个名为urls.py的文件,并在其中添加如下代码:

from django.conf.urls import url
from django.contrib.auth.views import login

from . import views

app_name='users'

urlpatterns = [
    # 登录页面
    url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'),
]

我们首先导入了默认视图login,登录页面的URL模式与URL http://localhost:8000/users/login/匹配。这个URL中的单词users让Django在users/urls.py中查找,而单词login让它将请求发送给Django默认视图login(请注意,视图实参为login,而不是views.login)。鉴于我们没有编写自己的视图函数,我们传递了一个字典,告诉Django去哪里查找我们将编写的模板。这个模板包含在应用程序users而不是learning_logs中。

1. 模板login.html
用户请求登录页面时,Django将使用其默认视图login,但我们依然需要为这个页面提供模板。为此,在目录learning_log/users中,创建一个名为templates的目录,并在其中创建一个名为users的目录。以下是模板login.html,你应将其存储到目录learning_log/users/templates/users/中:

{% extends "learning_logs/base.html" %}

{% block content %}

{% if form.errors %}
  

Your username and password didn't match. Please try again.

{% endif %}
{% csrf_token %} {{ form.as_p }}
{% endblock content %}

这个模板继承了base.html,旨在确保登录页面的外观与网站其他页面相同。请注意,一个应用程序中的模板可继承另一个应用程序中的模板
如果表单中的errors属性被设置,我们就显示一条错误消息。我们要让登录视图处理表单,因此将实参action设置为登录页面的URL。登录视图将一个表单发送给模板,在模板中,我们显示这个表单并添加一个提交按钮。我们还包含了一个隐藏表单的元素——'next', 其中的实参value 告诉 Django在用户成功登录后将其重定向到什么地方——这里是主页。

2. 链接到登录页面
在base.html中添加到登录页面的链接,让所有页面都包含它。用户已登录时,我们不想显示这个链接,因此将它嵌套在{% if %}标签中

# base.html

Learning Log - Topics - {% if user.is_authenticated %} Hello, {{ user.username }} {% else %} log in {% endif %}

{% block content %}{% endblock content %}

在Django身份验证系统中,每个模板都可使用变量user,这个变量有一个is_authenticated属性:如果用户已登录,该属性将为True,否则为False。对于还未通过身份验证的用户,我们再显示一个到登录页面的链接。

3. 使用登录页面
访问http://localhost:8000/users/login/, 你将看到类似于下图的登录页面,输入用户名和密码,将进入页面index。登录后,在这个主页的页眉中,显示了一条个性化问候语,包含你的用户名

Django Web应用程序(五)_第1张图片
登录页面

Django Web应用程序(五)_第2张图片
登录后页面

19.2.3 注销

现在需要提供一个让用户注销的途径。我们不创建用于注销的页面,而让用户只需单击一个连接就能注销并返回到主页。因此,我们将为注销连接定义一个URL模式,编写一个视图函数,并在base.html中添加一个注销链接。

1. 注销URL
下面的代码为注销定义了URL模式,该模式与URL http://localhost:8000/users/logout/匹配。修改后的users/urls.py如下

from django.conf.urls import url
from django.contrib.auth.views import login

from . import views

app_name='users'

urlpatterns = [
    # 登录页面
    url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'),
    # 注销
    url(r'^logout/$', views.logout_view, name='logout'),
]

这个URL模式将请求发送给函数logout_view()。这样给这个函数命名,旨在将其与我们将在其中调用的函数logout()区分开。(请确保你修改的是users/urls.py,而不是learning_log/ urls.py)。

2. 函数视图logout_view()
函数logout_view()很简单:只是导入Django函数logout(),并调用它,再重定向主页。请打开users/views.py,并输入下面代码

from django.shortcuts import render

from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth import logout

# Create your views here.
def logout_view(request):
    """注销用户"""
    logout(request)
    return HttpResponseRedirect(reverse('learning_logs:index'))

我们从django.contrib.auth中导入了函数logout(),调用函数logout(), 它要求将request对象作为实参。然后,我们重定向到主页。

3. 链接到在注销视图
现在我们需要添加一个注销链接。在base.html中添加这种链接,让每个页面都包含它,我们使得仅当用户登录后才能看到它。

# base.html

Learning Log - Topics - {% if user.is_authenticated %} Hello, {{ user.username }}. log out {% else %} log in {% endif %}

{% block content %}{% endblock content %}

下图显示了用户登录之后看到的页面。这里的重点是创建能够正确工作的网站,因此几乎没有设置任何样式。确定所需的功能都能正确运行后,我们将设置这个网站的样式,使其看起来更专业。


Django Web应用程序(五)_第3张图片
个性化问候语和注销链接的主页

19.2.4 注册页面

下面来创建一个让新用户能够注册的页面。我们将使用Django提供的表单UserCreationForm,但编写自己的视图函数和模板。
1. 注册页面的URL模式
下面的代码定义了注册页面的URL模式,它也包含在users/urls.py中:

from django.conf.urls import url
from django.contrib.auth.views import login

from . import views

app_name='users'

urlpatterns = [
    # 登录页面
    url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'),
    # 注销
    url(r'^logout/$', views.logout_view, name='logout'),
    # 注册页面
    url(r'^register/$', views.register, name='register'),
]

这个模式与URL http://localhost:8000/users/register/匹配,并将请求发送给我们即将编写的函数register()

2. 视图函数register()
在注册页面首次被请求时,视图函数register()需要显示一个空的注册表单,并在用户提交填写好的注册表单时对其进行处理。如果注册成功,这个函数还需让用户自动登录。在users/views.py中添加如下代码:

from django.shortcuts import render

from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import UserCreationForm

# Create your views here.
def logout_view(request):
    """注销用户"""
    logout(request)
    return HttpResponseRedirect(reverse('learning_logs:index'))

def register(request):
    """注册新用户"""
    if request.method != 'POST':
        # 显示空的注册表单
        form = UserCreationForm()
    else:
        # 处理填写好的表单
        form = UserCreationForm(data=request.POST)
        
        if form.is_valid():
            new_user = form.save()
            # 让用户自动登录,再重定向到主页
            authenticated_user = authenticate(username=new_user.username,
               password=request.POST['password1'])
            login(request, authenticated_user)
            return HttpResponseRedirect(reverse('learning_logs:index'))
            
    context = {'form': form}
    return render(request, 'users/register.html', context)

3. 注册模板

# register.html
{% extends "learning_logs/base.html" %}

{% block content %}

  
{% csrf_token %} {{ form.as_p }}
{% endblock content %}

这里也使用了方法as_p,让Django在表单中正确地显示所有的字段,包括错误信息——如果用户没有正确地填写表单。

4. 链接到注册页面
接下来,我们添加这样的代码,即在用户没有登录时显示到注册页面的链接:

Learning Log - Topics - {% if user.is_authenticated %} Hello, {{ user.username }}. log out {% else %} register log in {% endif %}

{% block content %}{% endblock content %}

现在未登录的用户看到的是注册链接和登录链接。


Django Web应用程序(五)_第4张图片
未登录用户界面

现在,我们能使用注册页面创建几个用户名各不相同的账户了!

你可能感兴趣的:(Django Web应用程序(五))