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 %}
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 %}
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 %}
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 %}