38
@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")
94
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'),
- [Django]-How to create a fixture file
- [Django]-Dynamic File Path in Django
- [Django]-MySQL "incorrect string value" error when save unicode string in Django
- [Django]-With DEBUG=False, how can I log django exceptions to a log file
- [Django]-Adding a user to a group in django
- [Django]-Where's my JSON data in my incoming Django request?
0
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,])
- [Django]-Empty Request.FILES with Django Upload forms
- [Django]-Converting timezone-aware datetime to local time in Python
- [Django]-Django – present current date and time in template