在这一节,我们将建立一个用户注册和身份认证系统,让用户能够注册账户,进而登录和注销
我们将创建一个新的应用程序,其中包含于处理用户账户相关的所有功能。
19.2.1 应用程序users
我们首先使用命令startapp来创建一个名为users的应用程序:
node2:/django/mysite/learning_log#python manage.py startapp users
node2:/django/mysite/learning_log#ls
db.sqlite3 learning_log learning_logs manage.py run.sh users
node2:/django/mysite/learning_log#
这个命令新建一个名为users的目录,其结构与应用程序learning_logs相同
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',
'blog',
'form',
'news',
'djcelery',
'home',
'django_celery_results',
'users',
]
这样,Django将把应用程序users包含到项目中:
2.包含应用程序users的URL
接下来,我们需要修改项目根目录中的urls.py,使其包含我们将为应用程序users定义的URL:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^users/', include('users.urls', namespace='users')),
url(r'', include('learning_logs.urls', namespace='learning_logs')),
]
node2:/django/mysite/learning_log/learning_log#cat urls.py
"""learning_log URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import include,url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^log/',include('learning_logs.urls',namespace='learning_logs')),
url(r'^users/', include('users.urls', namespace='users')),
]
我们添加了一行代码,以包含应用程序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的文件,并在其中添加入下代码:
""" 为应用程序 users 定义 URL 模式 """
from django.conf.urls import url
from django.contrib.auth.views import login
from . import views
urlpatterns = [
# 登录页面
url(r'^login/$', login, {'template_name': 'users/login.html'},
name='login'),
]
node2:/django/mysite/learning_log#cat users/urls.py
""" 为应用程序 users 定义 URL 模式 """
from django.conf.urls import url
from django.contrib.auth.views import login
from . import views
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去哪里查找我们将编写的模板。
node2:/django/mysite/learning_log/learning_log#cat urls.py
"""learning_log URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import include,url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^log/',include('learning_logs.urls',namespace='learning_logs')),
url(r'^users/', include('users.urls', namespace='users')),
]
1. 模板login.html
用户请求登录页面时,Django将使用其默认视图login,但我们依然为这个页面提供模板。
为此,在目录learning_log/users中,创建一个名为templates的目录
用户请求登录页面时, Django 将使用其默认视图 login ,但我们依然需要为这个页面提供模板。为此,在目录 learning_log/users/ 中,创建一个名为 templates 的目录,并在其中创建一
个名为 users 的目录。以下是模板 login.html ,你应将其存储到目录 learning_log/users/templates/users/ 中:
node2:/django/mysite/learning_log/users/templates/users#cat login.html
{% extends "learning_logs/base.html" %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url 'users:login' %}">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">log in</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}
这个模板继承了base.html,旨在确保登录页面的外观与网站的其他页面相同。请注意,
一个应用程序中的模板可继承另一个应用程序中的模板
如果表单的errors属性被设置,我们就显示一条错误消息,指出
输入的用户名--密码对于数据库中存储的任何用户名--密码对都不匹配
我们要让登陆视图处理表单,因此将实参action设置为登陆页面的URL。
登陆视图将一个表单发送给模板,在模板中,我们显示这个表单并添加一个提交按钮。
2.连接到登录页面
下面的base.html 中添加到登录页面的连接,让所有页面都包含它。
用户已登录时,我们不想显示这个连接,因此将它嵌套在一个 {% if %} 标签中:
<p>
<a href="{% url 'learning_logs:index' %}">Learning Log</a> -
<a href="{% url 'learning_logs:topics' %}">Topics</a> -
{% if user.is_authenticated %}
Hello, {{ user.username }}.
{% else %}
<a href="{% url 'users:login' %}">log in</a>
{% endif %}
</p>
{% block content %}{% endblock content %}
3.使用登录页面
node2:/django/mysite/learning_log/users#cat templates/users/login.html
{% extends "learning_logs/base.html" %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url 'users:login' %}">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">log in</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}