Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between using url tag and get_absolute_url

Tags:

django

If I have a model like this:

class Article(models.Model):
    title = models.CharField(max_length=200)
    # ... rest of the code ...

    def get_absolute_url(self):
        return reverse('article-detail', args=[str(self.pk)])

and I have an url mapping like this:

url(r'^article/(?P<pk>[0-9]+)/$', views.ArticleView.as_view(), name='article-detail'),

In template should I use:

<a href="{{ article.get_absolute_url }}">{{ article.title }}</a>

or

<a href="{% url 'article-detail' article.pk %}">{{ article.title }}</a>

I'm still thinking both are good ideas, but which is the best?

In the first code I've written args=[str(self.pk)], why I must convert self.pk into string? URLs must be strings?

In my generic view, how do I use pk variable? I'm really confused with that slug_field, slug_url_kwarg, pk_url_kwarg, query_pk_and_slug.

Which matches which?

If I set query_pk_and_slug to True, slug_field = pk?

like image 857
yierstem Avatar asked Aug 03 '26 03:08

yierstem


1 Answers

In my opinion,use

 <a href="{{ article.get_absolute_url }}">{{ article.title }}</a>

is better practice. If later on you want to change the url of this resource, you will do it once in your models function, and you would not search every template page for reference to this specific url. The philosophy behind this, is that the url for an article is a resource that belongs to the model of the article (django: Fat models and skinny controllers?)

A better approach, is to write

return reverse('article-detail', kwargs={'pk': self.pk})

This way, and when having multiple args in your url, you know every time the value of each arg (*args and **kwargs?)

I am not sure about the last part of your question. All in all, pk represents the primary key, which by default (and leave it as it) is the id (automatically produced by your database), and slug is a unique field in database (you specify it in your model definition) that represents a SlugField. Slug is used when you prefer more readable (seo) urls like /article/giannis-antetokounmpo-is-the-best, instead of /article/404.

For understanding how the class-based views work in django (better practice than function-based) take a look https://ccbv.co.uk/projects/Django/1.10/django.views.generic.detail/DetailView/ for example. When the GET (http method is called), the get function of the model is called as a result. If you notice, there is a self.get_object() function. In the definition of the get_object(), you can see the logic you are searching for. Specifically, in the comments, you can see all the ways, that View is trying to find the one and only object to return. You must choose one, by specifying the appropriate variables.

like image 112
Michael Marinos Likouras Avatar answered Aug 05 '26 20:08

Michael Marinos Likouras



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!