What does kwargs={'pk': self.pk} do in get_absolute_url method?

Viewed 604

I've finished a Django tutorial a few days ago and I've started to recap the functionalities in my application. In my models.py I've stumbled upon a method and the kwargs thing it's not that clearly to me. What is the logic behind this, can you explain to me what it does? Thank you.

models.py

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse

class Creation(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    likes = models.ManyToManyField(User, related_name='creation_posts')

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('blog:detail', kwargs={'pk': self.pk})

    def total_likes(self):
        return self.likes.count()

What does kwargs={'pk':self.pk}) do exactly? Thank you

3 Answers

When the get_absolute_url method is called upon it returns a reverse link to the URL at blog:detail and this will pass additional arguments to the URL, in this case being pk.

This will have been setup in the urls.py to something like the following.

path('blog/detail/<pk>', views.BlogDetail.as_view(), name="blog_detail")

In general, Based on kwarg documentation:

**kwargs allows you to handle named arguments that you have not defined in advance.

In a function call, keyword arguments must follow positional arguments.

All the keyword arguments passed must match one of the arguments accepted by the function (e.g. actor is not a valid argument for the parrot function), and their order is not important.

But in your case, kwargs pass pk variable to your blog:detail URL and you can use this value in your view

Same as url tag when passing arguments. That is,

{% url 'detail' pk = self.pk%} 

is equivalent to

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

It's just building a link based on the path name and if your path has url parameters, then based on them. Because if you have such a path (for example): path ('list / <int: post_id>', name = 'detail'). You cannot just take and write in the link {% url 'detail'%}, as there can be dozens or hundreds of such pages. And for this, arguments are passed, in this case the arguments id (model field) = cycle.id (id of each post in the cycle) will be passed. kwargs = {'pk': self.pk}) - this will build a link based on the path name - detail and arguments. Here it will be like this: pk-url-parameter will be equal to pk of each instance of the model class.

Related