【Django】(4)创建其他页面
创建完了网站的主页后,我们将创建两个显示数据的网页,一个列出所有的主题,另一个显示特定主题的所有条目。对于每个网页,都要指定其URL模式,编写一个视图函数,一个模板。这样做之前,可以先编写一个父模板,让项目中的其他模板都继承它。
1.模板继承
1-1.父模板
先创建一个base.html的模板,并将其储存在index.html 所在的目录中。base.html 包含所有页面都有的元素,其他模板都继承base.html。
base.html:
<p> <a href="{% url 'learning_logs:index' %}">learning_logs</a> </p> {% block content %} {% endblock content %}
其中{%%}是模板标签,href中的learning_logs:index生成一个URL,该URL与learning_logs/urls.py中定义的名为index的URL模式匹配。
其中learning_logs是一个命名空间,而index是该命名空间中的一个名称独特的URL模式匹配。
content为占位符,其中的信息由子模版来指定。子模版并非必须定义父模板中的每个块,因此在父模板中可使用任意多个content来预留空间,而子模版可根据需要定义相应数量的块。
1-2.子模版
现在需要重新编写index.html,使其继承base.html,如下所示:
index.html
{% extends "learning_logs/base.html" %} {% block content %} <p>Learning Log</p> <p>Learning Log helps you keep track of your learning,for any topic you're learning about.</p> {% endblock content %}
修改为如上,在块中填入HTML代码。这种继承的方式的好处是,当网页多了起来,管理的时候方便了许多。
2.显示所有主题的页面
2-1 URL模式
定义一个用来显示所有主题的主题的页面URL。http://localhost:8000/topics将返回显示所有主题的条目。
先修改learning_logs/urls.py:
urls.py
"""learing_logs应用程序中的URL模式""" from django.conf.urls import url from . import views urlpatterns = [ #主页 url(r'^$', views.index, name='index'), #显示所有的主题 url(r'^topics/$',views.topics,name='topics'), ] app_name = 'learning_logs' #自定义的应用程序的名字
在这里可以比较显示主页的代码,调用的视图函数不一样,前面调用views中的index,后者调用了views中的topics。
2-2.视图
还未在views.py中添加topics,所以现在来添加views.py中的代码。
from django.shortcuts import render from .models import Topic #使用到数据库时需要导入 # Create your views here. def index(request): #省略 def topics(request): topics = Topic.objects.order_by('data_added') context = {'topics': topics} return render(request, 'learning_logs/topics.html', context)
一定从model中导入Topic函数
2-3.模板
在index.html的同一目录下,新建一个topics.html,添加如下代码:
{% extends "learning_logs/base.html" %} {% block content %} <p>Topics</p> <ul> {% for topic in topics %} <li>{{topic}}</li> {% empty %} <li>No topics have been added yet.</li> {% endfor %} </ul> {% endblock content %}
其中的{% for item in list %} do somethong with each item {% endfor %} 在这个循环中,要将每个主题转化为一个项目列表项。要在模板中打印出变量,需要将变量名用双花括号括起来。每次循环时,代码
{{topic}}都将被替换为当前的topic的值
{% empty % } 告诉Django在列表为空时该如何处理。
现在需要修改父模板,使其包含到显示所有主题(topics.html)的页面的链接
<p> <a href="{% url 'learning_logs:index' %}">learning_logs</a> <a href="{% url 'learning_logs:topics' %}">topics</a> </p> {% block content %} {% endblock content %}
3.显示特定主题的页面
现在需要创建一个专注于特定主题的页面--显示该主题的名称以及该主题的所有条目。同样,将定义一个新的URL模式,编写一个视图并创建一个模板。还将修改显示所有主题的页面,让每个项目列表项都是一个链接,单击将显示相应的主题的所有条目。
3-1.URL模式
它将使用主题的id属性来指出请求的时哪个主题。例如,查看Chess(其id为1)的详细页面,URL 将为http://localhost:8000/topics/1/。现在修改learning_logs/urls.py:
"""learing_logs应用程序中的URL模式""" from django.conf.urls import url from . import views urlpatterns = [ #省略 url(r'^topics/(?P<topics_id>\d+)/$',views.topic,name='topic'), ] app_name = 'learning_logs' #自定义的应用程序的名字
?P<topics_id>\d+中,\d+是匹配一个数字,将匹配到的数字存入topics_id中
3-2.视图
#省略 def topic(request,topic_id): """显示单个主题及其所有条目""" topic = Topic.objects.get(id=topic_id) entries = topic.entry_set.order_by('-date_added') context = {'topic':topic,'entires':entries} return render(request, 'learning_logs/topic.html',context)
3-3.模板
在目录中添加topic.html,添加如下代码:
{% extends 'learning_logs/base.html' %} {% block content %} <p>Topic:{{topic}}</p> <p>Entries:</p> <ul> { for entry in entries } <li> <p>{{ entry.date_added|date:'M d, Y H:i' }}</p> <p>{{ entry.text|linebreaks}}</p> </li> {% empty %} <li>There are no entries for this topic yet.</li> {% endfor %} </ul> {% endblock content %}
为了将每个条目变成链接,还需要修改topics.html中的for循环:
{% for topic in topics %} <li><a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a></li> {% empty %} <li>No topics have been added yet.</li> {% endfor %}
如不成功,检查代码。
亲测效果如下: