《Tango with Django》-第14章 中期练习

14.0 汇总

为了丰富 Rango 应用的功能,提升交互性,最好再加上下述功能。

❏ 统计分类和网页的相关数据
• 分类的查看次数
• 网页的访问次数
• 分类的点赞次数(参见第 16 章)

❏ 在分类页面中集成过滤和搜索功能
• 删掉独立的搜索页面,让用户在分类页面就能搜索网页
• 让用户过滤分类,结果显示在侧边栏中(参见第 16 章)

❏ 为注册用户提供以下服务
• 假设你已经换用 django-registration-redux,修改注册表单,收集额外的信息(网站和头像)
• 让用户查看自己的个人资料
• 让用户编辑自己的个人资料
• 让用户查看用户列表及其他用户的个人资料

14.1 记录网页的访问次数

目前,Rango 直接提供外部网页的链接。如果想记录每个网页的访问次数,这样做不太合适。为了记录 Rango 应用中各网页的访问次数,要这么做:
❏ 编写一个视图,命名为 track_url(),把它映射到 URL /rango/goto/ 上,并设定’name=goto’ 参数。
❏ track_url() 视图从 HTTP GET 请求参数(例如 /rango/goto/?page_id=1)中获取page_id。
• 在视图中,通过 page_id 获取 Page 对象,增加它的 views 字段,然后保存。
• 使用 Django 的 redirect 函数把用户重定向到真正的 URL。
• 如果 HTTP GET 请求参数中没有 page_id,或者找不到对应的 Page 对象,重定向到首页。使用 django.core.urlresolvers 模块中的 reverse 函数获取 URL 字符串,然后重定向。如果使用的是 Django 1.10,可以从 django.shortcuts 模块中导入 reverse 函数。
• redirect 和 reverse 的更多信息参见 Django 文档。 ❏ 更新 category.html 模板,使用 /rango/goto/?page_id=XXX。记得使用 url 模板标签,不要硬编码 URL。
< a href="{% url ‘goto’ %}?page_id={ {page.id}}">

B.1 记录网页的访问次数

编写视图

在 /rango/views.py 模块中定义一个新视图,命名为 track_url()。这个视图从 HTTP GET 请求参数(rango/goto/?page_id=1)中提出所需的信息,更新相应网页的访问次数,然后重定向到真正的 URL。

from django.shortcuts import redirect
def track_url(request):
	page_id = None
	url = '/rango/'
	if request.method == 'GET':
		if 'page_id' in request.GET:
			page_id = request.GET['page_id']
			try:
				page = Page.objects.get(id=page_id)
				page.views = page.views + 1
				page.save()
				url = page.url
			except:
				pass
	return redirect(url)

别忘了在 views.py 模块顶部导入 redirect() 函数。

from django.shortcuts import redirect

添加 URL 映射

打开 /rango/urls.py 模块,把下述代码添加到 urlpatterns 中。

url(r'^goto/$', views.track_url, name='goto'),

修改分类页面的模板

修改 category.html 模板,不让用户点击真正的 URL,而是使用 rango/goto/?page_id=XXX。

{
    
    % for page in pages %}
<li>
	<a href="{% url 'goto' %}?page_id={
    
    {page.id}}">{
    
    {
    
     page.title }}</a>
	{
    
    % if page.views > 1 %}
		({
    
    {
    
     page.views }} views)
	{
    
    % elif page.views == 1 %}
		({
    
    {
    
     page.views }} view)
	{
    
    % endif %}
</li>
{
    
    % endfor %}

可以看到,我们根据 page.views 的值显示“view”、“views”,或者什么也不显示。

修改分类视图

既然已经记录了网页的访问次数,那么可以更改 category() 视图,按访问次数排序网页:

pages = Page.objects.filter(category=category).order_by('-views')

点击几个链接,然后返回分类页面,确认一切正常。再看看其他分类页面。

14.2 在分类页面中搜索

Rango 应用Ȃ在为用户提供对他们有帮助的网页。目前,搜索功能是独立于分类单独存在的。如果能集成到分类页面中的话更好。我们假设用户会先浏览感兴趣的分类,当用户找不到相关网页时,就可以搜索。如果用户找到感兴趣的网页,还可以把网页添加到分类中。现在我们先集中精力解决第一个问题,即在分类页面中添加搜索功能。具体步骤如下:
❏ 把导航栏中的搜索链接删除,即去掉独立的搜索功能。
❏ 把 search.html 模板中的搜索表单和结果展示代码移到 category.html 模板中。
❏ 修改搜索表单,把 action 属性的值改为当前分类页面:
< form class=“form-inline” id=“user_form” method=“post” action="{% url ‘show_category’ category.slug %}"> ❏ 更新 show_category() 视图,处理 HTTP POST 请求。还要把搜索结果传给上下文字典,以便在模板中渲染。
❏ 此外,限制只让通过身份验证的用户搜索。在 category.html 模板中要这样限制访问:

	{
    
    % if user.authenticated %}
		< !-- 在这插入搜索代码 -->
	{
    
    % endif %}

B.2 在分类页面中搜索

去掉搜索页面

首先要删除独立的搜索页面,只让用户在分类页面中搜索。为此,要删除现在的搜索页面及其视图。
然后,修改 base.html 模板,把导航栏中的“Search”链接删掉。rango/urls.py 模块中的 URL 映射也要删除。

添加搜索表单

打开 category.html 模板,在网页列表下方添加搜索表单。这与 search.html 模板中的代码差不多,但是要把 action 属性指向 show_category 页面。此外还要传入 query 变量,让用户知道自己搜索的是什么。

在这里插入代码片

别忘了把搜索表单和搜索结果放在 {% if user.authenticated %} 和 {% endif %} 之间,只让通过身份验证的用户搜索,以免访客浪费有限的 API 使用额度。

修改分类视图

修改 show_category() 视图,处理 HTTP POST 请求,并把搜索结果列表传给模板上下文。

在这里插入代码片

注意,context_dict 现在多了 result_list 和 query。如果没有搜索词条,使用默认的值,即分类名。这个值在搜索框中显示。

14.3 增加个人资料页面

如果你换用 django-registration-redux 包了,可能会想收集用户的个人资料。此时,不能把用户重定向到 Rango 应用的首页,而要重定向到一个新的表单,让用户提供头像和个人网站。基本步骤如下:
❏ 创建 profile_registration.html 模板,显示 UserProfileForm。 ❏ 定义 UserProfileFormModelForm 类,处理这个新表单。
❏ 编写 register_profile() 视图,捕获用户提供的个人信息。
❏ 把视图映射到 URL rango/register_profile/ 上。
❏ 修改 MyRegistrationView 类中的 get_success_url() 方法,把重定向地址改为 rango/add_profile/。

此外,还可以为用户提供查看和编辑个人资料的功能。基本步骤如下:
❏ 创建 profile.html 模板,显示一个表单,添加几个字段,分别显示用户的个人资料(用户名、电子邮件地址、网站和头像)。
❏ 编写 profile() 视图,获取渲染模板所需的数据。
❏ 把 profile() 视图映射到 URL /rango/profile/ 上。
❏ 修改基模板,在导航栏中添加“Profile”链接,最好与其他用户相关的链接放在一起。这个链接只有已登录的用户才能看到({% if user.is_authenticated %})。
为了让用户查看其他用户的个人资料,可以创建一个用户列表页面,列出全部用户。点击某个用户后便可查看他的个人资料。不过,必须确保用户只能修改自己的个人资料。

B.3 增加个人资料页面(跳过,我没有用用 django-registration-redux 包)

创建模板

定义 UserProfileForm 类

猜你喜欢

转载自blog.csdn.net/m0_46629123/article/details/113528898