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

  • Post category:Python

Django的get_absolute_url()函数是一个模型方法,它的作用是为模型提供一个可以访问其详情页面的URL。在Django的基于类视图的URL分发系统中,这个URL可以以类似”app_name:model_name:pk”的形式被构建。

get_absolute_url()函数简单而言,就是用来生成模型对象的URL链接。在某些情况下,我们可能需要在简单的方法返回中构造相应的URL,从而方便管理这些URL链接,此时我们会需要用到这个函数。

使用方法

在一个模型中,只需要添加一个get_absolute_url()方法,该方法返回的是一个由一个或多个参数构成的字符串类型的URL。这个方法的具体实现方式需要我们自己设定。

例如,我们有一个博客文章模型。在这个模型的对象方法(get_absolute_url)中,必须返回一个字符串,它指向这篇文章的绝对URL。当我们在HTML模板中使用{% url %}标签时,会自动帮我们构造URL:

# models.py 

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

class Blog(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=100, unique=True)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('blog_detail', args=[str(self.slug)])

以上模型在get_absolute_url方法中返回的链接是由reverse()函数生成的。它接收一个视图名称和必要的参数作为参数,并返回一个URL,以便在模板中和重定向中使用。注意参数顺序。

与此同时,在你的URL配置中,你需要有一个URL模式来匹配这个博客文章的URL,以便可以访问该URL:

# urls.py

from django.urls import path

from .views import BlogDetailView

urlpatterns = [
    path('<slug:slug>/', BlogDetailView.as_view(), name='blog_detail'),
]

在这个URL配置中,我们为访问blog_detail视图传递了一个slug参数。我们会在视图中使用这个slug来查找具有特定slug值的博客文章。

接下来,我们编写视图,将模型与模板连接起来:

# views.py

from django.views.generic import DetailView

from .models import Blog


class BlogDetailView(DetailView):
    model = Blog
    template_name = 'blog/blog_detail.html'

在这个视图中,我们使用Django的内置基于类的视图DetailView,并为它传递了Blog模型作为模型,使用了与相应的模板。

现在,我们可以使用get_absolute_url()函数,将链接添加到HTML模板中:

<!-- blog_detail.html -->

<h1>{{ object.title }}</h1>
<p>{{ object.content }}</p>

<a href="{{ object.get_absolute_url }}">Read More</a>

这样,当我们点击 “Read More” 链接时,它会将我们带到与该博客文章相关联的唯一URL。

使用实例

假设我们有一个Card模型,我们想要生成URL以显示唯一的Card,并通过一个slug字段来标识这个Card。

# models.py

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


class Card(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=100, unique=True)
    description = models.TextField(max_length=2000, default='')

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('card_detail', args=[str(self.slug)])

在这个例子中,我们将get_absolute_url()的实现过程中使用的reverse()函数的参数设置为视图函数的名称作为参数。我们的card_detail视图函数的视图名称为card_detail。这里注意”D”和”d”的大小写区分。我们还将这个函数的参数设置为slug,以便使用slug可以生成唯一的URL。

接下来,我们需要为我们的URL配置添加card_detail路由:

# urls.py

from django.urls import path
from .views import CardDetailView

urlpatterns = [
    path('<slug:slug>/', CardDetailView.as_view(), name='card_detail')
]

我们将slug参数传递给”card_detail”视图函数。请注意,由于我们的slug是唯一的,所以我们可以使用slug作为我们的通用标识符。

最后,我们需要定义CardDetailView视图函数:

# views.py

from django.views.generic import DetailView
from .models import Card


class CardDetailView(DetailView):
    model = Card
    template_name = 'card_detail.html'
    context_object_name = 'card'

这里我们使用了Django的内置DetailView类,将Card模型与card_detail函数连接起来,并将context_object_name设置为card。

现在,我们可以将get_absolute_url()用于我们在模板中的链接:

<!-- card_detail.html -->

<h1>{{ card.title }}</h1>
<p>{{ card.description }}</p>

<a href="{{ card.get_absolute_url }}">Back to Card</a>

这个<a>标签上的href属性将会使用get_absolute_url()函数中 相应Card的slug值 来自动构造正确的URL。