详解Django的 get_absolute_url() 函数:返回模型对象的 URL

  • Post category:Python

当使用Django来开发Web应用时,我们经常需要在各个视图间跳转,这就需要我们指定每个对象的URL. 为了方便地管理和访问对象的URL,Django提供了get_absolute_url()函数。

get_absolute_url()函数的作用

get_absolute_url()函数是Django中用于确定一个对象的URL的标准方法. 该方法需要返回是一个字符串,这个字符串就是该对象的Canonical URL。Canonical URL 是一个有规范的URL,一个URL canonicalization(URL规范化)过程最终得到一个Canonical URL.

get_absolute_url()方法的作用就是在每个Django对象中唯一地定义其规范URL,使得不同视图中可以直接使用该方法来获取对象的URL,而不需要重复编写URL。

实现get_absolute_url()方法

要实现get_absolute_url()方法,需要在模型类里头定义这个函数。

一个简单的例子:

from django.urls import reverse

class Blog(models.Model):
    title = models.CharField()
    summary = models.TextField()
    content = models.TextField()

    def get_absolute_url(self):
        return reverse("blog_detail", kwargs={"id": self.pk})

对于这个例子,get_absolute_url()函数只是简单地返回了一个Reverse URL的结果字符串. 这个结果字符串告诉Django应该使用哪个视图来展示这个URL对应的对象. 在这个例子中,这个函数返回了/blog/id这个URL模板,并通过传入的参数来占位符。因此,例如我们的blog对象的主键是2,那么该对象的规范URL就应该是/blog/2这个URL。

在模板中使用get_absolute_url()函数

在模板中使用get_absolute_url()函数非常容易,我们可以直接通过Django内置的{{ object.get_absolute_url }} 来获取对象的规范URL。

为了说明这个过程,我们举一个从新闻详情页跳转到新闻列表页的例子。首先,我们有一个News模型,该模型包含了 titledesc 以及 content信息:

from django.urls import reverse
from django.db import models

class News(models.Model):
    title = models.CharField()
    desc = models.CharField()
    content = models.TextField()

为了实现从新闻详情页跳转到新闻列表页的功能,我们需要在我们编写的URLConf中定义对应的URL,以及正确定义对应的视图.

对于新闻列表视图,可以在views.py文件中实现类似这样的代码:

from django.shortcuts import render
from myapp.models import News

def news_list_view(request):
    news_list = News.objects.all()
    return render(request, 'news_list.html', {'news_list': news_list})

对于新闻详情视图,可以在views.py文件中实现类似这样的代码:

from django.shortcuts import render, get_object_or_404
from myapp.models import News

def news_detail_view(request, pk):
    news = get_object_or_404(News, pk=pk)
    return render(request, 'news_detail.html', {'news': news})

我们还需要修改对应的URLConf以及对应的html文件:

url(r'^news-list/$', views.news_list_view, name='news_list'),
url(r'^news/(?P<pk>[0-9]+)/$', views.news_detail_view, name='news_detail'),
<!-- news_detail.html -->
<h2>{{ news.title }}</h2>
<p>{{ news.content }}</p>

<a href="{{ news.get_absolute_url }}">Back to News List</a>
<!-- news_list.html -->
{% for news in news_list %}
    <h2><a href="{{ news.get_absolute_url }}">{{ news.title }}</a></h2>
{% endfor %}

在html文件中,我们通过 ‘{{ news.get_absolute_url }}’来获取到我们想要的博客页面的完整路径。

结束语

get_absolute_url()函数是一个很实用的函数,通常情况下我们可以在使用 Django 的函数时提供参数。Django会根据参数将匹配的格式化好的 URL 返回。当你需要修改URL时,你不需要再修改到处都有你拼接URL字符串的地方,你只需要修改URLConf里的URL配置,get_absolute_url函数中的跳转方式也会自动跟着修改。

当我们把get_absolute_url方法应用到模型中时,可以大大简化模板中链接的生成代码,使它更加清净明了。