Django - Как я могу отправить абсолютный url для модели из views.py в другой скрипт python?
Я довольно новичок в Django и пытаюсь сделать модуль хлебных крошек. Он работает довольно хорошо, за исключением того, что у меня возникают проблемы при попытке сделать обратную ссылку на URL, для которых нужен первичный ключ.
У меня есть файл breadcrumbs.py, который просто просматривает список ключевых слов в списке и добавляет HTML в виде элементов списка.
Проблема заключается в том, что для обратной ссылки, например, на профиль пользователя, мне нужно отправить absolute_url для этого профиля в breadcrumbs.py. Однако, поскольку я вызываю функцию get_breadcrumbs из views.py, я не могу напрямую отправить объект запроса в качестве аргумента в дополнительном контексте.
models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
role = models.ForeignKey(Role, on_delete=models.SET_DEFAULT, blank= True, default=Role.get_default)
image = models.ImageField(default='profile_pics/default.png', upload_to = 'profile_pics')
def __str__(self) -> str:
return f"{self.user.username}'s profile"
def get_absolute_url(self):
return reverse("profile", kwargs={"pk": self.pk})
views.py:
from apps.backend_utils.breadcrumbs import get_breadcrumbs
class ProfileView(LoginRequiredMixin, DetailView):
model = Profile
template_name = 'users/users_profile.html'
extra_context = {
'breadcrumbs': get_breadcrumbs(['home']),
'page_title' : 'Profile',
}
breadcrumbs.py:
from django.urls import reverse_lazy
breadcrumb_lookup = {
'home': {
'title' : 'home',
'url_name': 'home',
'icon_class' : 'fas fa-home',
},
'profile': {
'title' : 'Profile',
},
...[Code omitted]...
}
for k, v in breadcrumb_lookup.items():
if 'url_name' in v.keys():
v.update({'url': reverse_lazy(v['url_name'])})
breadcrumb_lookup.update({k: v})
def get_breadcrumbs(crumb_list: list):
return [breadcrumb_lookup[c] for c in crumb_list if c in breadcrumb_lookup]
Я использую его в своем шаблоне как:
{% for crumb in breadcrumbs %}
{% if crumb.title == 'home' %}
<li class="nav-home">
{% else %}
<li class="nav-item">
{% endif %}
{% if crumb.url %}
<a href="{{ crumb.url }}">
{% else %}
<a href="#">
{% endif %}
{% if crumb.icon_class %}
<i class="{{ crumb.icon_class }}"> </i>
{% else %}
<span>{{ crumb.title }}</span>
{% endif %}
</a>
</li>
{% if not forloop.last %}
<li class="separator">
<i class="flaticon-right-arrow"></i>
</li>
{% endif %}
{% endfor %}
Я мог бы получить запрос из метода dispatcher, а затем сохранить его в extra_context. Затем я мог бы модифицировать метод get_context, чтобы передать absolute_url в метод get_breadcrumbs, но это кажется большой работой для простой функциональности (и я предполагаю, что есть лучший способ).
class ProfileView(LoginRequiredMixin, DetailView):
model = Profile
template_name = 'users/users_profile.html'
extra_context = {
'page_title' : 'Profile',
}
def dispatch(self, request, *args, **kwargs):
self.extra_context['profile_url'] = request.user.profile.get_absolute_url()
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['breadcrumbs'] = get_breadcrumbs(['home', 'profile'], profile_url = context['profile_url'])
В качестве альтернативы я также могу просто перенаправить пользователя на его собственный профиль, изменив URL на другой вид для перенаправления на профиль пользователя, но это кажется плохим способом сделать это.
class ProfilePageRedirectView(LoginRequiredMixin, TemplateView):
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(request.user.profile.get_absolute_url())
Я знаю, что Django имеет свое мнение, и хотел бы узнать, как сделать это правильно.