11

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!

1
  • 1
    What does the appropriate line in your urlconf look like? And what error does Django throw at you? Commented Jan 5, 2013 at 11:27

5 Answers 5

25

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.

Sign up to request clarification or add additional context in comments.

2 Comments

According to the 1.6 docs, the permalink decorator is no longer recommended: docs.djangoproject.com/en/1.6/ref/models/instances/…
According to the django docs you need to use reverse() docs.djangoproject.com/en/2.1/ref/models/instances/…
12

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"

2 Comments

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.
@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.
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

Comments

0

This function worked for me, it uses multiple parameters:

def get_absolute_url(self):
return reverse('video', kwargs={'slug':self.chapiter.course.slug,'chpiter_slug':self.chapiter.chpiterSlug,'pk':str(self.index).zfill(2)})

1 Comment

Could you explain why/how that works? Also, are 'chapiter' and 'chpiter' supposed to be 'chapter'?
0

Here is how you do it in Django >= 2.0.

In urls.py

from django.urls import path

app_name = 'my_app'

urlpatterns = [
    path('products/<slug:slug>', views.ProductDetailView.as_view(), name='products')
]

Add the following code to your models.py

class Product(models.Model):
    name = models.CharField(max_length=125)
    slug = models.SlugField(unique=True)
    # rest of the fields

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

For displaying the detail, add a generic view in your views.py

class ProductDetailView(DetailView):
     template_name = 'my_app/detail.html'

     def get_queryset(self):
         return Product.objects.all()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.