GENERAL CONTEXT
- My understanding of this related post and the get_absolute_url() Django docs section is essentially that get_absolute_url() is useful and preferred because using it 1) allows templates to be more generic, 2) reduces the number of places to update if a change is needed / check if a problem arises, and 3) is used in the django admin app etc. to make links work.
- I recently posted this question about using get_absolute_url() where get_absolute_url() is on a model and the main problem I had was that I was missing the context data in the right view.
EXAMPLE PROJECT STRUCTURE CONTEXT
Note: I used excerpts where possible to avoid clutter
I have a _base.html file that includes a header. One functioning link in the header’s dropdown menu is:
<li><a class="dropdown-item" href="{% url 'profile_list' %}">Profile List</a></li>
I have a profiles app that includes:
Profile model using get_absolute_url()
class Profile(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False)
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
def get_absolute_url(self):
return reverse("profile_detail", args=[str(self.id)])
URLs
from django.urls import path
from .views import ProfileListView, ProfileDetailView
urlpatterns = [
path("", ProfileListView.as_view(), name="profile_list"),
path("<uuid:pk>", ProfileDetailView.as_view(), name="profile_detail"),
]
View
from django.views.generic import ListView, UpdateView
from .models import Profile
class ProfileListView(ListView):
model = Profile
context_object_name = "profile_list"
template_name = "profiles/profile_list.html"
class ProfileDetailView(UpdateView):
model = Profile
context_object_name = "profile"
template_name = "profiles/profile_detail.html"
Template - profiles/profile_list.html
{% for profile in profile_list %}
<div class="card mb-3" style="max-width: 540px;">
<div class="row g-0">
<div class="col-md-4">
<img src="{% static 'images/testimage.jpg' %}" class="img-fluid rounded-start" alt="Profile Image">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">{{ profile.user.username }}</h5>
<p class="card-text"><a href="{{ profile.get_absolute_url }}">{{ profile.user.username }}</a></p>
<br />
<p class="card-text"><small class="text-body-secondary">{{ profile.date_modified }}</small></p>
</div>
</div>
</div>
</div>
{% endfor %}
Template - profiles/profile_detail.html
<h1>{{ profile.user.username }}'s Profile</h1>
I have a pages app that includes static pages, one of which is the following:
URL
from django.urls import path
from .views import AboutPageView
urlpatterns = [
path("about/", AboutPageView.as_view(), name="about"),
]
View - Created with help from this post about using get_absolute_url()
class AboutPageView(TemplateView):
template_name = "pages/about.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["my_profile"] = self.request.user.profile
return context
Template
<a href="{{ my_profile.get_absolute_url }}">My Profile</a>
QUESTIONS
1a. Why does the link for the Profile List in the _base.html header menu not need context data in a _base.html view file to work? Is it because the {% url %} tag can be used without passing anything except the URL name in?
1b. Is get_absolute_url() preferred for template links like this (aka: non-detail page related links) too? If yes, how would you update this profile list link as an example? Would adding the below to the Profile model work? / Can there be more than one get_absolute_url() per model class?
def get_absolute_url(self):
return reverse("profile_list")
2a. If I wanted to add a link to the _base.html header menu that links to the authenticated user’s profile, it seems like I need to create a _base.html view file; is that correct?
2b. If yes, is it normal to just have a _base.html view file kind of free floating in the main folder of the project (like in the same folder as the manage.py file?). In other words, I’m used to having the views files be within the app folders but since the _base file isn’t app-specific I want to know if there’s a certain place a related view file normally goes. If no, how/where would you put the context you need for the link to work?