Django中url的逆向解析 -> Reverse resolution of URLs

之前的一篇文章中介绍了url的基本用法[ Django的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()

以一个简单的博客url规则来举例说明,导航页面如下

导航条的category都是从数据库读出的数据,其中每个category都是形如 /blog/category/category_name的超链接,具体如下
  • /blog/category/home/
  • /blog/category/python/
  • /blog/category/android/
  • /blog/category/reading/
因此我们的url规则可以设计成如下形式
url(r'^category/(?P<cat_name>\w+)/$', 'category', name='list_category'),
这样category的名字会被当做参数传递给 category这个view.同时给这条url规则命名为 list_category.
模板文件中,生成导航条的代码如下
    <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规则
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())
                  })


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值