Дублирование категорий в Django

Govard

Новичок
Пользователь
Апр 21, 2020
22
4
3
Здравствуйте ещё раз!)
В прошлый раз вы мне в очередной раз помогли и всё заработало как я хотел. Но я пошел дальше и опять наткнулся на проблему с которой уже не могу справиться более суток. Прошу вашей помощи))

В прошлый раз вы мне помогли с:
nAynlX9ugMev3r.jpg

Всё корректно и классно отображается.
Но когда я перехожу например в категорию месяца "Январь", то у меня появляется повторение категорий месяца:
ZrJQxqpcwzl00A.jpg

Записи гороскопов отображаются корректно, а вот категории месяцев почему-то дублируются и если создать новую запись в категорию месяца "Январь", то будет выглядеть так:
J2b6d53f0OWLa2.jpg

Как мне сделать так, чтобы при переходе в определенный месяц категорий был только один заголовок, а не дублировались месяца?)

views.py
Python:
class HoroscopeDetailView(DetailView):
    model = Horoscope
    context_object_name = 'horoscopes_items'

    def get_queryset(self):
        return Horoscope.objects.all()

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        self.object.views += 1
        self.object.save()
        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)


class HoroscopeByCategory(ListView):
    model = CategoryHoroscopes
    context_object_name = 'categories'

    def get_queryset(self):
        # попытаться получить категорию
        category = get_object_or_404(CategoryHoroscopes, slug__iexact=self.kwargs.get('slug'))
        # вывести новости из категории
        queryset = category.horoscopes.all()
        return queryset


class HoroscopePage(ListView):
    template_name = 'news/horoscope.html'
    context_object_name = 'categories'

    def get_queryset(self):
        return CategoryHoroscopes.objects.all().order_by('pk')[0:6]

urls.py

Python:
    path('horoscope/<slug>/', HoroscopeDetailView.as_view(), name='horoscope'),
    path('category-horoscopes/<slug>/', HoroscopeByCategory.as_view(), name='category-horoscopes'),
    path('horoscopes/', HoroscopePage.as_view(), name='horoscopes'),

models.py

Python:
class Horoscope(models.Model):
     title = models.CharField(max_length=150, verbose_name='Заголовок гороскопа')
     content = models.TextField(blank=False, verbose_name='Текст гороскопа')
     photo = models.ImageField(upload_to='photos_horosсope/%Y/%m/%d/', verbose_name='Картинка гороскопа', blank=True)
     slug = models.SlugField(max_length=150, unique=True, verbose_name='Слаг гороскопа')
     views = models.IntegerField(default=0, verbose_name='Просмотры')
     category_horoscopes = models.ForeignKey('CategoryHoroscopes', verbose_name='Месяц', on_delete=models.PROTECT, related_name='horoscopes')  # on_delete=models.PROTECT - защита от удаления статей привязанных к категории.

     def get_absolute_url(self):
          return reverse('horoscope', kwargs={"slug": self.slug})

     def __str__(self):
          return self.title

     def save(self, *args, **kwargs):
         value = self.title
         self.slug = slugify(value)
         super().save(*args, **kwargs)

     class Meta:
          verbose_name = 'Гороскоп'
          verbose_name_plural = 'Гороскопы'
          ordering = ['-title']  # '-created_ad' - посты в обратном порядке. Свежие первые.


class CategoryHoroscopes(models.Model):
     title = models.CharField(max_length=150, db_index=True, verbose_name='Категория гороскопа')
     slug = models.SlugField(max_length=150, unique=True, verbose_name='Слаг категории')

     def get_absolute_url(self):
          return reverse('category-horoscopes', kwargs={"slug": self.slug})

     def __str__(self):
          return self.title

     def save(self, *args, **kwargs):
         value = self.title
         self.slug = slugify(value)
         super().save(*args, **kwargs)

     class Meta:
          verbose_name = 'Категория гороскопа'
          verbose_name_plural = 'Категории гороскопов'
          ordering = ['title']

horoscope_list.html

HTML:
{% include 'inc/_nav.html' %}

<body>
<div class="color-main-horoscope">
    <div id="col-horoscope">

        {% for item in categories %}
        <a href="{% url 'category-horoscopes' item.category_horoscopes.slug %}"><h3>{{ item.category_horoscopes.title }}</h3></a>
        {% endfor %}

        {% for item in categories %}
        <a href="{% url 'horoscope' item.slug %}"><h3>{{ item }}</h3></a>
        {% endfor %}
    </div>
    </div>
</div>
<div id="space-5">

</div>
</body>

P.S. Надеюсь я вам не надоел... Я правда пытаюсь сначала решить проблему сам и если совсем попадаю в тупик, то обращаюсь к вам за помощью. Надеюсь на ваше понимание!)
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Как мне сделать так, чтобы при переходе в определенный месяц категорий был только один заголовок, а не дублировались месяца?)
Проще всего - использовать DetailView вместо LIstView, так как по сути вам нужна информация о категории (название и список гороскопов внутри нее), а не список категорий.
Вот пример:
views.py
Python:
from django.views.generic import ListView, DetailView

from .models import Horoscope, CategoryHoroscopes


class HoroscopePage(ListView):
    template_name = 'horoscope.html'
    context_object_name = 'categories'

    def get_queryset(self):
        return CategoryHoroscopes.objects.all()


class HoroscopeByCategory(DetailView):
    model = CategoryHoroscopes
    template_name = 'horoscope_list.html'
    context_object_name = 'category'


class HoroscopeDetailView(DetailView):
    model = Horoscope
    context_object_name = 'horoscope'
    template_name = 'horoscope_detail.html'
и шаблоны для примера:
horoscope.html
HTML:
<body>
{% for category in categories %}
    <h2><a href="{{ category.get_absolute_url }}">{{category}}</a></h2>
    <ul>
        {% if category.horoscopes.all %}
            {% for horoscope in category.horoscopes.all %}
                <h3>{{horoscope}}</h3>
            {% endfor%}
        {% endif %}
    </ul>
{% endfor %}
</body>
horoscope_list.html
HTML:
<body>
<h2>{{ category.title }}</h2>
{% for horoscope in category.horoscopes.all %}
    <h3><a href="{{ horoscope.get_absolute_url }}">{{ horoscope.title }}</a></h3>
{% endfor %}
</body>
horoscope_detail.html
HTML:
<body>
<h2>{{ horoscope.title }}</h2>
<p>{{ horoscope.content }}</p>
</body>
 
  • Мне нравится
Реакции: Govard

Govard

Новичок
Пользователь
Апр 21, 2020
22
4
3
Проще всего - использовать DetailView вместо LIstView, так как по сути вам нужна информация о категории (название и список гороскопов внутри нее), а не список категорий.
Вот пример:
views.py
Python:
from django.views.generic import ListView, DetailView

from .models import Horoscope, CategoryHoroscopes


class HoroscopePage(ListView):
    template_name = 'horoscope.html'
    context_object_name = 'categories'

    def get_queryset(self):
        return CategoryHoroscopes.objects.all()


class HoroscopeByCategory(DetailView):
    model = CategoryHoroscopes
    template_name = 'horoscope_list.html'
    context_object_name = 'category'


class HoroscopeDetailView(DetailView):
    model = Horoscope
    context_object_name = 'horoscope'
    template_name = 'horoscope_detail.html'
и шаблоны для примера:
horoscope.html
HTML:
<body>
{% for category in categories %}
    <h2><a href="{{ category.get_absolute_url }}">{{category}}</a></h2>
    <ul>
        {% if category.horoscopes.all %}
            {% for horoscope in category.horoscopes.all %}
                <h3>{{horoscope}}</h3>
            {% endfor%}
        {% endif %}
    </ul>
{% endfor %}
</body>
horoscope_list.html
HTML:
<body>
<h2>{{ category.title }}</h2>
{% for horoscope in category.horoscopes.all %}
    <h3><a href="{{ horoscope.get_absolute_url }}">{{ horoscope.title }}</a></h3>
{% endfor %}
</body>
horoscope_detail.html
HTML:
<body>
<h2>{{ horoscope.title }}</h2>
<p>{{ horoscope.content }}</p>
</body>

Спасибо огромное вам)) если честно у меня эта мысль была, чтобы изменить List на Detail, но я подумал, что она бредовая))) Оказалось, что в этом и была проблема)) Ещё раз вам огромное спасибо)) Надеюсь я вам не надоел))
 

Форум IT Специалистов