Пытаюсь отобразить название текущего тега, т.е. того, в котором мы находимся. Не получается. Как правильно написать для отображения тега в шаблоне?
#Models
from django.db import models
from taggit.managers import TaggableManager
class Blog(models.Model):
title = models.CharField(max_length=150)
created_at = models.DateTimeField(auto_now_add=True)
description = models.CharField(max_length=550)
tags = TaggableManager()
def __str__(self):
return self.title
#Views
from django.shortcuts import render
from django.views.generic import ListView
from .models import *
from taggit.models import Tag
class TagMixin(object):
def get_context_data(self, **kwargs):
context = super(TagMixin, self).get_context_data(**kwargs)
context['tags'] = Tag.objects.all()
return context
class PostIndexView(TagMixin,ListView):
model = Blog
template_name = 'blog.html'
queryset=Blog.objects.all()
context_object_name = 'posts'
class TagIndexView(TagMixin,ListView):
model = Blog
template_name = 'blog.html'
context_object_name = 'posts'
def get_queryset(self):
return Blog.objects.filter(tags__slug=self.kwargs.get('tag_slug'))
#Templates
{% if tag %}
<h3>Posts by tag: {{ tag }}</h3> <!-- Does not display tag name -->
{% endif %}
P.s. Сайт просит больше описания, но что здесь еще можно описать? Описана проблема с выводом
Предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.
если я правильно понимаю - в вашем шаблоне нет переменной tag
. У вас есть tags
. В этом случае:
#Templates
{% for tag in tags %}
<h3>Posts by tag: {{ tag }}</h3>
{% endfor %}
если вы хотите иметь в контексте специальный тег tag_slug — вам следует добавить его в контекст вручную, как вы это делаете с помощью tags
. Или вы можете использовать эту конструкцию:
#Templates
{% if view.kwargs.tag_slug %}
<h3>Posts by tag: {{ view.kwargs.tag_slug }}</h3>
{% endif %}
Также, если вы хотите иметь только один текущий тег, вам следует его отфильтровать:
class TagMixin(object):
def get_context_data(self, **kwargs):
context = super(TagMixin, self).get_context_data(**kwargs)
context['tags'] = Tag.objects.all()
context['tag'] = Tag.objects.filter(slug=self.kwargs.get('tag_slug', '')).first()
return context
Кстати, __str__
всегда должен возвращать тип str. Предпочтительно прямое преобразование в строку:
class Blog(models.Model):
def __str__(self):
return f'{self.title}'
В новом Python вы можете объединять словари и иметь пустой супер, а классы по умолчанию являются дочерними элементами object
:
class TagMixin:
def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs) | {'tags' : Tag.objects.all()}
Для общего ListView вам не нужно определять одновременно queryset
и model
. Одного из них достаточно. Определите, что queryset
на пару микросекунд быстрее, чем model
. Также вам не нужно переопределять имя шаблона и context_object_name. Просто используйте blogs_list
и blogs_app/blogs_list.html
по умолчанию.
class PostIndexView(TagMixin,ListView):
queryset=Blog.objects.all()
# Thats all, you dont need any other attributes
я добавляю это в свой ответ
Правильно ли я понимаю, что в вашем примере мы выводим все теги? Я хотел бы вывести имя текущего тега. Не все теги
@Ajex - см. мой ответ. во втором примере я показываю только текущий "tag_slug"
Ага. Работает. Спасибо большое, Максим. Это именно то, что мне нужно!)
добро пожаловать. Но я добавляю фильтр по тегам и в ответ
Спасибо. Система не позволяет мне, как новичку, проголосовать за ваш ответ)
@Ajex просто примите ответ, чтобы закрыть этот вопрос как завершенный.
Похоже я поторопился..... Теперь получаем имя тега из слизняка. Можно ли получить имя тега из имени? Все дело в том, что в пуле между словами стоит знак «-».
В своем ответе я добавляю объект «тег» в контекст. в шаблоне вы можете получить его как {{ tag.name }}
Спасибо, Максим. Теперь все в порядке)
Поделитесь своими моделями.