How do I generate absolute urls in Django template?

Question:

I’m having trouble generating the absolute url for a Django model. In "courses.html" template I iterate through two models, category and course, but am only able to generate the relative url <slug> rather than the full url /courses/<slug> from each object.

Is there any way to generate an absolute url for each object?

main views.py

def courses(request):
    return render(request=request,
                  template_name="main/courses.html",
                  context={'courses': Course.objects.all,
                           'categories': Category.objects.all},
                  )

courses.html


{% extends "main/header.html" %}
{% block content %}

{% for category in categories %}
    <a href="{{ category.slug }}"/>
      <p>{{ category }}</p>
    </a>
{% endfor %}

{% for course in courses %}
    <a href="{{ course.slug }}"/>
      <p>{{ course }}</p>
    </a>
{% endfor %}
Asked By: Masquerade

||

Answers:

Problem

Get absolute url for a model object that correlates with a url.

Solution

A common idiosyncrasy in django is to define get_absolute_url on the model and use reverse to build the url with context from the model. Keeping business logic contextual to the model in the model simplifies maintenance and automated testing. This pattern is used throughout the Django framework (ie: https://github.com/django/django/blob/555e3a848e7ac13580371c7eafbc89195fee6ea9/tests/contenttypes_tests/models.py#L16-L20).

Example

urls.py

...
    path('<int:course_id>/', views.CourseDetail.as_view(), name='course_detail'),
    path('<int:category_id>/', views.CategoryDetail.as_view(), name='category_detail'),
...

models.py

class Course(models.Model):
    def get_absolute_url(self):
        return reverse('course_detail', kwargs={"id": str(self.id)})

class Category(models.Model):
    def get_absolute_url(self):
        return reverse('category_detail', kwargs={"id": str(self.id)})

courses.html

{% extends "main/header.html" %}
{% block content %}

{% for category in categories %}
    <a href="{{ category.get_absolute_url }}"/>
      <p>{{ category }}</p>
    </a>
{% endfor %}

{% for course in courses %}
    <a href="{{ course.get_absolute_url }}"/>
      <p>{{ course }}</p>
    </a>
{% endfor %}
Answered By: pygeek
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.