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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With