8.动态 URL 匹配一个具体 topic 页面
8.动态 URL 匹配一个具体 topic 页面
Django Shell 可以在交互式的终端中查看数据库中的数据
python manage.py shell
from learning_logs.models import Topic
Topic.objects.all() # 返回所有的 Topic 对象
# 获取一个对象后,就可以查看这个对象的各个属性
t = Topic.object.get(id=1)
# 重点是还可以查看关联 Topic 的 Entry
t.entry_set.all() # 返回与这个 Topic 相关联的所有 entry 对象
上述的 topics 页面已经是个动态页面了,根据数据库中实际的 Topic 数据的不同生成内容不同的 html 文件返回给 /home/topics/ 这个 path。现在让 url 也动态起来,上代码
learning_logs/url.py
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'^$', views.index, name='index'),
re_path(r'^index$', views.index, name='index'),
re_path(r'^topics$', views.topics, name='topics'),
re_path(r'^topics/(?P<topic_id>\d+)', views.topic, name='topic'),
]
可以看到一个全新的表达式——(?P<topic_id>\d+)
- ( ) 括号表示捕获 URL 中的两个斜杠 / / 之间的值
- ?P<topic_id> 表示将值存到名为 topic_id 的实参中
- \d+ 表示包含在 / / 之间的所有数字都匹配,+ 表示1 位或多位
learning_logs/views.py
from django.shortcuts import render
from .models import Topic
## Create your views here.
def index(request):
return render(request, 'learning_logs/index.html')
def topics(request):
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
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)
learning_logs/template/learning_logs/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, H:i' }}</p>
<p>{{ entry.text|linebreaks }}</p>
</li>
{% empty %}
<li>There are no entries for this topic yet</li>
{% endfor %}
</ul>
{% endblock content %}
这样一套 链接(URL)视图(view)模板(template)三连下来,用户就可以动态的访问到具体的 Topic 内容了,/home/topics/1, /home/topics/2, /home/topics/N...
当然现代社会了,不会让用户手动输入 URL 里面的参数的,都是做成页面上的链接去点击就可以了。那现在来改下 topics.html 模板
learning_logs/template/learning_logs/topics.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li>
<a href="{% url 'learning_logs:topic' topic.id %}">{{ topic.text }}</a>
</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}
这样就给 topic.text 加上了一个链接,注意 url 'learning_logs:topic' 里的 topic 和引号 之外的 topic 不是一回事哦,外面的 topic 是整个页面中 topics 的一个元素,而 topics 是 views.topics 传进来的一组对象。learning_logs:topic 是只 lerarning_logs 这个 namespace 里名为 topic 的 url pattern (urls.py),上述也讲过了,这里估计又忘了再次提一下。
总结:链接(URL)视图(view)模板(template)三连