Get Absolute URL in Django when using Class Based Views

26,967

Solution 1

You should always give your URLs a name, and refer to that:

url(r'/category/(?P<slug>\w+)/$', CategoryView.as_view(), name='category_view'),

Now:

@models.permalink
def get_absolute_url(self):
    return ('category_view', (), {'slug': self.slug})

Note I've used the permalink decorator, which does the same as calling reverse but is a bit neater.

Solution 2

Here is my get_absolute_url configuration:

urls.py

urlpatterns = patterns('',
    url(r'^products/(?P<slug>[\w\d\-\_]+)/$', views.ProductView.as_view(), name='product'),
    )

models.py

def get_absolute_url(self):
    return reverse('products:product', kwargs={'slug':self.slug})

My urls.py is under the "products" app, so the url namespace is "products:product"

Solution 3

The 2018 answer to this question is basically the same as @Aaron's, but for quick access here it is:

def get_absolute_url(self):
    from django.urls import reverse
    return reverse('people.views.details', args=[str(self.id)])

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

Share:
26,967
Ayman Farhat
Author by

Ayman Farhat

I enjoy everything related to programming. Web, and software development is what I do.

Updated on July 21, 2022

Comments

  • Ayman Farhat
    Ayman Farhat almost 2 years

    Hello I am migrating my app to use class based views instead of function based views. In my old code I was able to get the absolute URL of an object related to a function view this way:

    class Category(models.Model):
        name = models.CharField(max_length=100,unique=True)
        slug = models.SlugField(unique=True)
        description = models.TextField()
        parent = models.ForeignKey('self',null=True,blank=True)
    
        def get_absolute_url(self):
            return reverse('blog.views.showcategory',args=[str(self.slug)])
    

    I couldn't find what I should change in my get absolute url function in order to get the same result.

    This is my new class based view

    class CategoryView(ListPosts):
        template_name = "postlist.html"
        context_object_name="posts"
        def get_queryset(self):
             return Post.objects.filter(category__slug=self.kwargs['slug']).order_by('created')
    

    Thanks!

    • Daniel Eriksson
      Daniel Eriksson over 11 years
      What does the appropriate line in your urlconf look like? And what error does Django throw at you?
  • highpost
    highpost about 10 years
    According to the 1.6 docs, the permalink decorator is no longer recommended: docs.djangoproject.com/en/1.6/ref/models/instances/…
  • Reveclair
    Reveclair about 9 years
    And if the regexp were not named like so : url(r'^products/([\w\d\-_]+)/$', views.ProductView.as_view(), name='product'), ) how you would inject the parameter kwargs ? kwargs = self.slug does not work.
  • Aaron Lelevier
    Aaron Lelevier about 9 years
    @Reveclair kwargs is a key word argument dictionary, so you wouldn't want to set it equal to self.slug. You can inject parameters into kwargs like any other python dictionary. i.e. kwargs['foo'] = 'bar'. In addition, for Django, only named URL parameters get injected into kwargs, so it is important to name them in the URL regex.
  • mech
    mech about 6 years
    Could you explain why/how that works? Also, are 'chapiter' and 'chpiter' supposed to be 'chapter'?
  • nmu
    nmu over 5 years
    According to the django docs you need to use reverse() docs.djangoproject.com/en/2.1/ref/models/instances/…