Как воспользоваться self.kwargs вне CBV ? (Django)
Приступил к изучению Джанго и вот нарвался на такую проблему. Подскажите, пожалуйста, можно ли как то использовать конструкцию self.kwargs[] вне Class Based View?
Объясню: Есть представление:
Сlass NewsByCategory(ListView):
model = News
template_name = 'news/home_news_list.html'
context_object_name = 'news'
allow_empty = False
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs) # контекст модели
context['title'] = Category.objects.get(pk=self.kwargs['category_id'])
return context
def get_queryset(self):
return News.objects.filter(category_id=self.kwargs['category_id'], is_published=True)
Есть путь из url.py:
path('category/<int:category_id>/', NewsByCategory.as_view(extra_context={'title': 'Какой-то тайтл'}),
name='category'),
И есть кастомный тэг:
@register.inclusion_tag('news/list_categories.html')
def show_categories(arg1='Hello', arg2='World'):
categories = Category.objects.all()
return {'categories': categories, 'arg1': arg1, 'arg2': arg2}
Данный кастомный тэг рендерит шаблон:
<div class="list-group">
{%for item in categories%}
<a href="{{ item.get_absolute_url }}" class="list-group-item list-group-item-action">{{item.title}}</a>
{% endif %}
{%endfor%}
</div>
Зачем мне это надо: Сейчас при помощи данного тэга создаётся боковая панелька в которой выводятся ссылки на новости с конкретной категорией. Так вот я бы хотел, чтобы на странице с новостями определённой категории, ссылка на эту же страницу была не активна. т.е. если к примеру открыта страница с новостями о спорте, то хотелось бы, чтобы в боковой панели были активны ссылки на все остальные страницы, кроме текущей.
вот как я примерно вижу шаблон боковой панели:
<div class="list-group">
{%for item in categories%}
{% if item.pk != self.kwargs['category_id'] %}
<a href="{{ item.get_absolute_url }}" class="list-group-item list-group-item-action">{{item.title}}</a>
{% elif %}
<p class="selected">{{item.title}}</p>
{% endif %}
{%endfor%}
</div>
Осталось понять как реализовать это в кастомном тэге...
Спасибо!
Ответы (1 шт):
Ты же уже передаешь некие аргументы arg1 и arg2 в шаблонный тег. так передай текущий id категории туда. а текущую категорию ты и так уже добавляешь в контекст шаблона
@register.inclusion_tag('news/list_categories.html')
def show_categories(arg1='Hello', arg2='World', cur_category=None):
categories = Category.objects.all()
return {'categories': categories, 'arg1': arg1, 'arg2': arg2, 'cur_category': cur_category}
<div class="list-group">
{%for item in categories%}
{% if item.pk != cur_category %}
<a href="{{ item.get_absolute_url }}" class="list-group-item list-group-item-action">{{item.title}}</a>
{% elif %}
<p class="selected">{{item.title}}</p>
{% endif %}
{%endfor%}
</div>
ну вот как пример. имеем набор магазинов (далее shop) и набор продуктов (products). Каждый продукт привязан к магазину.
{% for item in shops %}
{% if item.pk == shop_id %}
<span> {{ item }} </span>
{% else %}
<a href="/newapp/{{ item.pk }}/">{{ item }}</a>
{% endif %}
{% endfor %}
код тега
@register.inclusion_tag('newapp/inctag.html')
def show_shops(shop_id=None):
shops = models.Shop.objects.all()
return {"shop_id": shop_id, "shops": shops}
и код страницы где этот тег используется
{% load shop_extras %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% show_shops title.pk %}
</body>
</html>
А код вьюхи я у тебя взял. Только модели свои поставил
class NewsByCategory(ListView):
model = models.Product
template_name = 'newapp/index.html'
context_object_name = 'news'
allow_empty = False
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs) # контекст модели
context['title'] = models.Shop.objects.get(pk=self.kwargs['shop_id'])
return context
def get_queryset(self):
return models.Product.objects.filter(shop__id=self.kwargs['shop_id'])