Django中url的逆向解析 -> Reverse resolution of URLs
阿新 • • 發佈:2019-02-16
之前的一篇文章中介紹了url的基本用法[Django的url用法]
解析的過程可以概括為
導航條的category都是從資料庫讀出的資料,其中每個category都是形如/blog/category/category_name的超連結,具體如下 這個view.同時給這條url規則命名為
URL request -> view calling
同時,django又提供了另一種解析方式 - Reverse resolution of URLs
它的解析過程為 view calling -> URL request
因為Django奉行的是DRY原則,所以使用這種方式,就無需對url地址進行硬編碼.在原本需要硬編碼url的地方,直接可以使用url的名字,然後逆向解析出url地址.
Django提供了不同層面上的url解析方法.
- template檔案: 用url模板標籤
- python程式碼中可以使用django.core.urlresolvers.reverse()
- 其他get_absolute_url()
導航條的category都是從資料庫讀出的資料,其中每個category都是形如/blog/category/category_name的超連結,具體如下
- /blog/category/home/
- /blog/category/python/
- /blog/category/android/
- /blog/category/reading/
url(r'^category/(?P<cat_name>\w+)/$', 'category', name='list_category'),
這樣category的名字會被當做引數傳遞給category
list_category
.
模板檔案中,生成導航條的程式碼如下
如果文章列表需要分頁,可以再新增一個url規則<nav id="site-nav"> {% for name in cat_all %} <a name="{{ name }}" href="{% url 'list_category' name %}" class="{% if name == cat_now %}active{% endif %}">{{ name|capfirst }}</a> {% endfor %} </nav>
url(r'^category/(?P<cat_name>\w+)/page/(?P<page_num>\d+)/$', 'category', name='page')
分頁顯示的模板程式碼
{% if posts.object_list and posts.paginator.num_pages > 1 %}
<footer>
{% if posts.has_previous %}
<a href="{% url 'page' cat_now posts.previous_page_number %}"><</a>
{% endif %}
<span>
{{ posts.number }} of {{ posts.paginator.num_pages }}
</span>
{% if posts.has_next %}
<a href="{% url 'page' cat_now posts.next_page_number %}">></a>
{% endif %}
</footer>
{% endif %}
最後是view的程式碼from django.shortcuts import render
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from blog.models import Post, Category
def category(request, cat_name, page_num=1):
if cat_name.lower() == 'home':
posts = Post.objects.all().order_by('-date')
else:
posts = Post.objects.all().filter(category__name=cat_name).order_by('-date')
paginator = Paginator(posts, 3)
try:
page = int(page_num)
except ValueError:
page = 1
try:
posts = paginator.page(page)
except (InvalidPage, EmptyPage):
posts = paginator.page(paginator.num_pages)
return render(request, 'blog/index.html',
{
'posts': posts,
'cat_now': cat_name,
'cat_all': map(lambda cat: cat.name, Category.objects.all())
})