显示特定主题的页面

接下来,我们需要创建一个专注于特定主题的页面——显示该主题的名称及该主题的所有条目。同样,我们将定义一个新的URL模式,编写一个视图并创建一个模板。我们还将修改显示所有主题的网页,让每个项目列表项都是一个链接,单击它将显示相应主题的所有条目。

URL模式

显示特定主题的页面的URL模式与前面的所有URL模式都稍有不同,因为它将使用主题的id属性来指出请求的是哪个主题,不懂没关系,结合代码就能明白。例如,如果用户要查看主题Chess的详细页面,URL将为http://localhost:8000/topics/1/,哦,你看,在url上可以有一些操作了,就跟你在百度网盘经常能看到的后缀一样。下面是与这个URL匹配的模式,它包含在learning_logs/urls.py中:

--snip--
urlpatterns = [
    --snip--
    #特定主题的详细页面
    url(r'^topics/(?P,topic_id>\d+)/$',views.topic,name='topic'),
}

我第一感受,这是个加了个什么东西,下面再详细研究,话说起来,事实上我用的并不是这个样子的,所以等会分析完之后我会掏出能用的代码。这个代码已经过时了,分析完之后我再晒出实际使用的代码吧。

r的作用是将字符视为原始字符串,并指出正则表达式包含在引号内。这个表达式的第二部分与包含在两个斜杠内的整数匹配,并将这个整数存储在一个名为topic_id的实参中。这部分表达式两边的括号捕获URL中的值;?P<topic_id>将匹配的值存储到topic_id中;而表达式\d+与包含在两个斜杠内的任何数字都匹配,不管这个数字为多少位。发现URL与这个模式匹配时,Django将调用视图函数topic(),并将存储在topic_id中的值作为实参传递给它。在这个函数中,我们将使用topic_id的值来获取相应的主题。如此一来更新了url,也就是更新了URL模式,感觉有很重要的地方没弄明白,先放一边,摆上正确结果然后进下一章。

re_path(r'^topics/(?P<topic_id>\d+)/$',views.topic,name='topic')

其实就是把url函数替换成了re_path

视图

函数topic()需要从数据库中获取指定的主题以及与之相关联的所有条目,如下所示

--snip--
def topic(request,topic_id):
    '''显示单个主题及其所有的条目'''
    topic = Topic.objects.get(id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic: topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

注意到,这个视图函数除request外还包含另一个形参的视图函数。这个函数接受正则表达式(?P<topic_id>\d+)捕获的值,并将其存储到topic_id中。get()用于获取指定的主题,就像前面在Django shell中所做的那样。然后获取与主题相关联的条目,并将它们按照date_added排序:date_added前面的减号指定按降序排列,即先显示最近的条目。我们将主题和条目都存储在字典context中,再将这个字典发送给模板topic.html。那么,总结一下,这个视图函数我没搞得很懂啊。看看在模板部分会不会讲解怎么使用。

模板

这个模板需要显示主题的名称和条目的内容;如果当前主题不包含任何条目,我们还需向用户指出这一点:

这里模板啥样我就不打出来了,我直接说明一下怎么搞的

像这个项目的其它页面一样,这里也继承了base.html。接下来,我们显示当前的主题,它存储在模板变量{{ topic }}中。为什么可以使用变量topic呢?因为它包含在字典context中,我们看到视图函数里context起到这个作用了。接下来,我们开始定义一个显示每个条目的项目的项目列表,并像前面显示所有主题一样遍历条目。

每个项目列表项都将列出两项信息:条目的时间戳和完整的文本。为列出时间戳,我们显示属性date_added的值。zaiDjango模板中,竖线|表示模板过滤器——对模板变量的值进行修改的函数。过滤器date: 'M d, Y H:i'以这样的格式显示时间戳:January 1,2015 23:30。接下来的一行显示text的完整值,而不仅仅是entry的前50个字符。这样的写法我曾经见过,这就是格式的作用,这个格式可以看出来,就是月,日,年,时,最后一个i似乎是表示秒,不,不是表示秒,而是表示分钟(minute),因为m跟月份的M重复了,所以用i来表示分钟。过滤器linebreaks将包含换行符的长条目转换为浏览器能够理解的格式。现在我明白了,竖线后面的东西是函数,而且是函数中的一个种类,叫做模板过滤器的种类。说回linebreaks,这个过滤器将包含换行符的长条目转换为浏览器能够理解的格式,以免显示为一个不间断的文本块。行列破坏者?是这个意思吗。使用模板标签{% empty %}打印一条消息,告诉用户当前主题还没有条目。

将显示所有主题的页面中的每个主题都设置为链接

在浏览器中查看显示特定主题的页面前,我们需要修改模板topics.html,让每个主题都链接到相应的网页,怕你忘了提醒一下,topics.html这个模板是用来显示主题的,不理解主题是什么?那就是你忘了我们这个网页是用来干什么的,以及网页上有些什么内容,这部分的内容甚至不在显示页面的教程里,这属于数据库的内容,你需要熟悉自己的网页有什么。那么,网页的新加内容如下所示:

--snip--
    {% for topic in topics %}
     <li>
      <a href="{% url 'learning_Logs:topic' topic.id %}">{{ topic }}</a>
     </li>
    {% empty %}
--snip--

我们又见到了{% empty %},这是一种模板标签,它会打印一条消息,告诉用户当前主题还没有条目。继续解释这一模板所添加的内容,我们使用模板标签url根据learning_logs中名为topic的URL模式来生成合适的链接。这个URL模式要求提供实参topic_id,因此我们在模板标签url中添加了属性topic.id。现在,主题列表中的每个主题都是一个链接,链接到显示相应主题的页面。

如果你刷新显示所有主题的页面,再单击其中的一个主题,你将看到类似于图18-5的页面。

这样一来,对流程算是大概熟悉了,这也是我看的第二遍了。就像打游戏有多个周目一样,我认为我还需要新的读一遍,才能掌握这一章的知识,才算是入门了Django,算是学会了网站是怎么做的,以及怎样去实现我想要的功能,和网站需要些什么样的东西

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值