Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Absolute URL in Django when using Class Based Views

Tags:

python

django

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!

like image 217
Ayman Farhat Avatar asked Jan 05 '13 09:01

Ayman Farhat


People also ask

How do I get an absolute URL in Django?

Use handy request. build_absolute_uri() method on request, pass it the relative url and it'll give you full one. By default, the absolute URL for request. get_full_path() is returned, but you can pass it a relative URL as the first argument to convert it to an absolute URL.

How do you know if a URL is absolute or relative in Python?

You can use the urlparse module to parse an URL and then you can check if it's relative or absolute by checking whether it has the host name set.

What is the difference between path and URL in Django?

In Django 2.0, you use the path() method with path converters to capture URL parameters. path() always matches the complete path, so path('account/login/') is equivalent to url('^account/login/$') . The part in angle brackets ( <int:post_id> ) captures a URL parameter that is passed to a view.


2 Answers

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"

like image 145
Aaron Lelevier Avatar answered Sep 28 '22 13:09

Aaron Lelevier


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.

like image 40
Daniel Roseman Avatar answered Sep 28 '22 15:09

Daniel Roseman