创建用户账户

下面的部分也许会有趣一点,将建立一个用户注册和身份验证系统,让用户能够注册账户,进而登录和注销。我们将创建一个新的应用程序,其中包含与处理用户账户相关的所有功能。我们还将对模型Topic稍做修改,让每个主题都归属于特定用户。这里,对于每个用户都要分别处理了,而且我们终于要给这个网站加一个新的应用程序了

应用程序users

我们首先使用命令startapp来创建一个名为users的应用程序,这次时隔多时又要用到命令行窗口啦:

python manage.py startapp users

使用这句命令,新建了一个名为users的目录,其结构与应用程序learning_logs相同

将应用程序users添加到settings.py中

在settings.py中,我们需要将这个新的应用程序添加到INSTALLED_APPS中,如下所示:

--snip--
INSTALLED_APPS = [
--snip--
    
    # My apps
    'learning_logs',
    'users',
]
--snip--
包含应用程序users的URL

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

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

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

我们添加了一行代码,以包含应用程序users中的文件urls.py。这行代码与任何以单词users打头的URL都匹配。我们还创建了命名空间'users',以便将应用程序learning_logs的URL同应用程序users的URL区分开来。(什么是命名空间?)

登录界面

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

'''为应用程序users定义URL模式'''

from django.urls import path
from django.contrib.auth.views import LoginView

from . import views

urlpatterns = [
	# 登录页面
	path('login/', LoginView.as_view(template_name='users/login.html'),
		name='login'),
]

此处与教科书上有一些不同,将其改成了能在现在使用的模式。

模板login.html
{% extends 'learning_logs/base.html' %}

{% block content %}
  
  {% if from.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。登录视图将一个表单发送给模板,在模板中,我们显示这个表单并添加一个提交按钮。我们还包含了一个隐藏的表单元素——‘next’,其中的实参value告诉Django在用户成功登录后将其重新定向到什么地方——这里是主页。

链接到登录页面

下面在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 %}

在Django身份验证系统中,每个模板都可使用变量user,这个变量有一个is_authenticated属性:如果用户已登录,该属性将为True,否则为False。这让你能够向已通过身份验证的用户显示一条消息,而向未通过身份验证的用户显示另一条消息。

在这里,我们向已登录的用户显示一条问候语。还有属性username,用用户名来问候。如果未通过身份验证,则再链接到登录页面。

注销

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

注销URL

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

--snip--
urlpatterns = [
	# 登录页面
	--snip--
	# 注销
	path('logout/', views.logout_view, name='logout'),
]

这个URL请求发送给函数logout_view()。这样给这个函数命名,旨在将其与我们将在其中调用的函数logout()区分开来。

视图函数logout_view()

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

from django.http import HttpResponseRedirect
from django.core.urlresolvers 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对象作为实参。然后,我们重定向到主页。

链接到注销视图

现在我们需要添加一个注销链接。这个链接用到得很多,在任何页面都要有一个返回主页的按键。于是我们在base.html中添加这种链接,让每个页面都包含它;我们将它放在标签{% if user.is_authenticated%}中,使得仅当用户登录后才能看到它:

--snip--
  {% if user.is_authenticated %}
    Hello, {{ user.username }}.
    <a href="{% url 'users:logout' %}">log out</a>
  {% else %}
    <a href="{% url 'users:login' %}">log in</a>
  {% endif %}
--snip--

注册页面

先考虑了注销,之后我们来考虑注册。下面来创建一个让新用户能够注册的页面。我们将使用Django提供的表单UserCreationForm,但编写自己的视图函数和模板。

注册页面的URL模式

下面的代码定义了注册页面的URL模式,它也包含在users/urls.py中:

--snip--
urlpatterns = [
--snip--
	# 注册页面
	path('register/', views.register, name='register'),
]

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

视图函数register()

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

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers 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):
--snip--
	
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)
注册模板

接下来先把这个功能完成了。注册页面的模板与登录页面的模板类似,请务必将其保存到login.html所在的目录中:

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

{% block content %}

  <form method="post" action="{% url 'users:register' %}">
    {% csrf_token %}
    {{ form.as_p }}
    
    <button name="submit">register</button>
    <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
  </form>
  
{% endblock content %}
链接到注册页面
--snip--
  {% if user.is_authenticated %}
    Hello, {{ user.username }}.
    <a href="{% url 'users:logout' %}">log out</a>
  {% else %}
    <a href="{% url 'users:register' %}">register</a> -
    <a href="{% url 'users:login' %}">log in</a>
  {% endif %}
--snip--

现在,已登录的用户看到的是个性化的问候语和注销链接,而未登录的用户看到的是注册链接和登录链接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值