基于How To Tango With Django 1.9的重新实践(17)——Hints

如果你能够根据我们上一章的提示完成练习就太好了,如果不能的话这章将会给你一些提示和代码来帮助你完成.

17.1 跟踪页面点击

目前Rango直接提供了外部页面的链接.对于要统计每个页面点击和浏览次数很不利.为了计算通过Rango浏览一个页面的次数你需要完成下面几个步骤.

17.1.1 创建URL跟踪视图

在/rango/views.py里创建一个叫做track_url()的新视图,它将会获取HTTPGET请求的参数(例如rango/goto/?page_id=1)并且修改浏览页面的次数.

def track_url(request):
    page_id = None
    if request.method == 'GET':
        if 'page_id' in request.GET:
            page_id = request.GET['page_id']
    if page_id:
        try:
            page = Page.objects.get(id=page_id)
            page.views = page.views + 1
            page.save()
            return redirect(page.url)
        except:
            return HttpResponse("Page id {0} not found".format(page_id))
    print("No page_id in get string")
    return redirect(reverse('index'))

17.1.2 映射URL

在/rango/urls.py里为urlpatterns元组增加下列代码.

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

17.1.3 修改目录模板

修改category.html模板的链接,使用户点击时访问rango/goto/?page_id=XXX而不是直接访问链接

{% extends 'rango/base.html' %}
{% load staticfiles %}
{#{% load bootstrap_toolkit %}#}

{% block title_block %}
    {{ category.name }}
{% endblock %}

{% block body_block %}
    <div>
        {#如果category存在#}
        {% if category %}
            <h1>{{ category.name }}</h1>
            {%  if pages %}
                <ul>
                    {% for page in pages %}
                    {#修改category.html模板的链接,使用户点击时访问rango/goto/?page_id=XXX而不是直接访问链接#}
                    <li>
                        <a href="{% url 'goto' %}?page_id={{ page.id }}"\>{{ page.title }}</a>
                        <span class="tag tag-pill tag-primary">
                            {% if page.views > 1 %}
                                ({{ page.views }} views)
                            {% elif page.views == 1 %}
                                ({{ page.views }} view)
                            {% endif %}
                        </span>
                    </li>
                    {% endfor %}
                </ul>
            {% else %}
                <strong>No pages currently in category.</strong>
            {% endif %}
        {#如果category不存在#}
        {% else %}
            <p>The specified category does not exist!</p>
        {% endif %}
        <a href="/rango/">时光鸡</a>
    </div>
{% if user.is_authenticated %}
<div>
    <h1>Search with Rango</h1>
    <br>
    <form action="{% url 'show_category' category.slug %}" class="form-inline" id="user_form" method="post">
        {% csrf_token %}
        <div class="form-group">
            <input type="text" class="form-control" size="50" name="query" value="{{ query }}" id="query">
        </div>
        <button class="btn btn-primary" type="submit" name="submit" value="Search">Search</button>
    </form>

    <div>
        {% if result_list %}
        <h3>Results</h3>
        <!-- 展示搜索的结果在一个有序的list中 -->
        <div class="list-group">
            {% for result in result_list %}
            <div class="list-group-item">
                <h4 class="list-group-item-heading">
                    <a href="{{ result.link }}">{{ result.title }}</a>
                </h4>
                <p class="list-group-item-text">{{ result.summary }}</p>
            </div>
            {% endfor %}
        </div>
        {% endif %}
    </div>
</div>
{% endif %}
{% endblock %}

17.1.4 修改目录视图

因为我们我们需要追踪点击数,你需要修改category()视图使页面按照浏览次数排序,例如:

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

17.2 在目录页搜索

我们首先需要移除先前添加的搜索功能然后只让用户在目录页面进行搜索.这意味着我们需要删除现在的搜索页面和搜索视图.我们需要完成下面的步骤.

17.2.1 移除搜索

把search.html代码放入category.html中.确定action指向category()视图.

<form class="form-inline" id="user_form" method="post" action="{% url 'category'  category.slug %}">
     {% csrf_token %}
     <!-- Display the search form elements here -->
     <input class="form-control" type="text" size="50" name="query" value="{{query}}" id="query" />
     <input class="btn btn-primary" type="submit" name="submit" value="Search" />
</form>

在底部添加<div>来存放搜索结果.

<div class="panel">
        {% if result_list %}
        <div class="panel-heading">
                <h3 class="panel-title">Results</h3>
                <!-- Display search results in an ordered list -->
                <div class="panel-body">
                <div class="list-group">
                        {% for result in result_list %}
                    <div class="list-group-item">
                        <h4 class="list-group-item-heading"><a href="{{ result.link }}">{{ result.title }}</a></h4>
                        <p class="list-group-item-text">{{ result.summary }}</p>
                    </div>
                {% endfor %}
            </div>
        </div>
    {% endif %}
</div>

17.2.3 修改目录视图

修改category视图来活的HTTP POST请求(例如当用户提交一个搜索)并且把结果列表存入上下文中.下面的代码实现这个功能.

def show_category(request,category_name_slug):
    #创建一个我们可以传递给模板渲染引擎(template rendering engine)上下文字典(context_dict),
    context_dict = {}

    # 我们可以找到具有给定名称的类别名称(category_name_slug)吗?
    try:
        #如果可以.get()方法返回一个模型实例
        category = Category.objects.get(slug=category_name_slug)

        #检索所有的相关页面,filter()将会返回一个包含page objects的list或者一个空list
        pages = Page.objects.filter(category=category).order_by('-views')

        #将结果list添加到name pages下的模板上下文中
        context_dict['pages'] = pages

        #把category object从数据库加入到上下文字典中
        #我们将会使用这个在template中检验指定category的存在
        context_dict['category'] = category

    #如果不能,.get()方法引发DoesNotExist异常
    except Category.DoesNotExist:

        #template将会显示“no category”
        context_dict['category'] = None
        context_dict['pages'] = None


    # 此处添加的新代码用于处理POST请求,根据要在搜索框中显示的category.name创建默认查询
    context_dict['query'] = category.name

    result_list = []
    if request.method == 'POST':
        query = request.POST['query'].strip()

        if query:
            #运行我们的search API功能来获取结果list
            result_list = run_query(query)
            context_dict['query'] = query
            context_dict['result_list'] = result_list

    #渲染响应并将其返回到客户端
    return render(request, 'rango/category.html', context_dict)

注意到在我们传递的context_dict字典里我们包含了resut_list和query,如果没有请求,我们将提供一个默认的请求,例如目录名.然后请求框会现实这个变量.

17.3 创建UserProfile实例

这个先不写了,先试试ajax是怎么玩的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值