Hi there,
the key idea is: *Let's have URLs defined at one and only one place.*

So, when you have urls.py like this:

urlpatterns = patterns('',
        '^blog/(?P<slug>\w+)', BlogDetail.as_view(), name='blog-detail',
        '^articles/(?P<slug>\w+)', ArticleDetail.as_view(),
                                                name='article-detail'
        '^$', HomepageView.as_view(), name='homepage')

Your urls are defined:

/ -- Homepage
/blog/<slug> -- Blog detail (eg. one entry)
/artices/<slug> -- Article detail (eg. one article)


Imagine you want to point some link to one of these pages. Hard-coded
links, like:

<!-- navigation.html -->
<a href="/">Homepage</a>
<a href="/blog/{{ blog.slug }}">{{ blog.title }}</a>
<a href="/articles/{{ article.slug }}">{{ article.title }}</a>

are bad. Because now are your urls defined at two places -- urls.py and
navigation.html. When you change urls.py, you have to update
navigation.html also. Right now, it's not such a problem, just two
files. Imagine that your project contains lot of templates, lot of
views and you have to change everything everytime when you change
urls.py. That's 1) boring and 2) very fragile. You'll probably spend a
huge amount of time with fixing bugs.

So, there's a solution:

Reverse url from urls.py for given parameters. Let's say you want link
to blog entry and you know the slug:

url = reverse('blog-detail', [], {'slug': slug})

So, our template could look like this:

<!-- navigation.html -->
{% load url from future %}
<a href="{% url "homepage" %}"></a>
<a href="{% url "blog-detail" slug=blog.slug %}">{{ blog.title }}</a>
<a href="{% url "article-detail" slug=article.slug %}">{{ article.title }}</a>

Now all links are "reversed" from urls.py. That's good, but again: When
you change urls.py, let's say you change blog url to:

/blog/<year>/<month>/<slug>

you'll have to change all your templates again! And that's boring.

So, another improvement: Every model instance should have it's own url
(every model instance should be identified somehow). Therefore it's
convenient to define get_absolute_url method:

def get_absolute_url(self):  # return url which points to this instance
        return reverse('blog-detail', [], {'slug': slug})

But usually we use 'reverse' function every time, so it's probably
easier to use method decorator:


@models.permalink
def get_absolute_url(self):
        return ('blog-detail', [], {'slug': slug})

and return only arguments for 'reverse' function.


Now, in you template, you can use:

<!-- navigation.html -->
{% load url from future %}
<a href="{% url "homepage" %}"></a>
<a href="{{ blog.get_absolute_url }}">{{ blog.title }}</a>
<a href="{{ article.get_absolute_url }}">{{ article.title }}</a>

and be happy ever after :)


Note: For me the documentation was clear. Could you please suggest any
improvement?

Link:
https://docs.djangoproject.com/en/1.5/ref/models/instances/#get-absolute-url


Cheers,
 Tom

http://www.tomas-ehrlich.cz/en/

"Půjdu kamkoliv, pokud je to kupředu." - J. London


Dne Fri, 16 Nov 2012 07:03:08 -0800 (PST)
enemytet <dominikan...@gmail.com> napsal(a):

>  
> 
> How (and why) to use @models.permalink and get_absolute_url? 
> 
> Please an example to better understand this. An example of the 
> documentation is not clear to me
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to