What is @permalink
and get_absolute_url
in Django? When and why to use it?
Please a very simple example (a real practical exam
in Django 2.1 The django.db.models.permalink() decorator is removed.
source
As of 2013, the Django documentation discouraged use of the permalink decorator and encouraged use of reverse() in the body of the get_absolute_url method. By 2015, the permalink decorator seemed to have vanished without a trace from the Django documentation, and it was finally removed in Django version 2.1 in 2018.
So, for a standard DRY way to create a permanent link to a single object view, use get_absolute_url() in your model like this:
from django.db import models
from django.urls import reverse
# NOTE: pre Django 1.10+ this is "from django.core.urlresolvers import reverse"
class MyModel(models.Model):
slug = models.SlugField()
def get_absolute_url(self):
return reverse('mymodel_detail', args=(self.slug,))
and then have an entry in urls.py that points to your view:
url(r'^(?P<slug>[-\w\d\_]+)/$',
MyModelDetailView.as_view(),
name='mymodel_detail'),
A better approach is to declare a name for your app in urls.py and then refer to that instead of hard coding anything:
in urls.py:
app_name = 'my_app'
urlpatterns = [
path('blogs/<int:slug>', blog.views.blog_detail, name='mymodel_detail'),
]
and in models.py:
from django.urls import reverse
class BlogPost(models.Model):
name = modelsCharField()
slug = models.SlugField(...)
def get_absolute_url(self):
return ('my_app:mymodel_detail, args=[self.slug,])
@permalink
is a python decorator, while get_absolute_url
is a method on a django model.
Both are concerned with allowing you to reverse the URL for a particular object and should be used together. They are used anytime you need to provide a link to a particular object or want to display that object's specific URL (if it has one) to the user
You could simply write your get_absolute_url
method to return a hard coded string, but this wouldn't adhere to Django's philosophy of DRY (don't repeat yourself). Instead, there is the @permalink
to make things more flexible.
If you read the docs on the subject you will see how they relate to each other. the @permalink
decorator hooks into django's URLconf's backend, allowing you to write much more portable code by using named url patterns. This is preferable to just using get_absolute_url
on it's own: your code becomes much DRYer as you don't have to specify paths.
class BlogPost(models.Model):
name = modelsCharField()
slug = models.SlugField(...)
@permalink
def get_absolute_url(self):
return ("blog-detail", [self.slug,])
and in urls.py
...
url(r'/blog/(?P<slug>[-w]+)/$', blog.views.blog_detail, name="blog-detail")