Journal page filter names were too long. I decided to display different filter names.
First filter names
To use the bootstrap logic from the free HTML-CSS-Bootstrap template, I had to create filter names with a slugified name. The name of the journal instance was the ideal option.
# journal/views.py
from django.views.generic import ListView
from journal.models import Journal
class JournalListView(ListView):
model = Journal
template_name = "journal.html"
context_object_name = "entries"
queryset = Journal.journal_published.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["filter_entries"] = self.get_filter_entries()
return context
def get_filter_entries(self):
filter_entries = set()
for entry in self.queryset.values('name'):
filter_entries.add(slugify(entry))
return filter_entries
Legend:
get_filter_entries()
: This function iterates over all Journal instances. It takes each name
value from the Journal instance, slugs it, and adds it to a set()
.But you can image that the slug: "doros-python-life-in-words-journal" is really long to display as a filter name. So, I decided to use a different approach.
Edited version
A filter name should be a short name, so I decided to acreate new attribute in the Journal model, called: category
. The category
attribute as a ForeignKey to the Category model. The Category model has a name
attribute, a slug
, published
, created
and updated
.
It is now easier to search the category from a journal and have these category names, which will be the filter names, displayed in the browser.
# journal/views.py
from django.views.generic import ListView
from journal.models import Journal
class JournalListView(ListView):
model = Journal
template_name = "journal.html"
context_object_name = "entries"
queryset = Journal.journal_published.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["filter_entries"] = self.get_filter_entries()
return context
def get_filter_entries(self):
filter_entries = set()
for entry in self.queryset.filter(category__name__isnull=False).values_list(
"category__name", "category__slug"
):
filter_entries.add(entry)
return filter_entries
Legend:
values_list()
: I am filtering for all category names which are not None
, and I am querying the category name and the category slug. To create a filter name attribute, I need a spaceless or slugified name. The category name is displayed in the browser and the category slug is used as the filter name to filter for a category.<!-- journal/templates/journal.html -->
{% extends 'base.html' %}
{% load i18n %}
{% block content %}
<!-- ======= Journal Section ======= -->
<section class="journal portfolio section-show">
<div class="container">
<div class="section-title">
<h2>{% trans "Journal" %}</h2>
</div>
<div class="row">
<div class="col-lg-12 d-flex justify-content-center">
<ul id="page-filters">
<li data-filter="*" class="filter-active">{% trans "All" %}</li>
{% for entry in filter_entries %}
<li data-filter=".filter-{{ entry.1 }}">{{ entry.0 }}</li>
{% endfor %}
</ul>
</div>
</div>
<div class="row page-container">
{% for entry in entries %}
<div class="col-lg-3 col-md-5 mt-4 portfolio-item filter-{{ entry.category.slug }}">
<div class="icon-box">
<h4><a href="{{ entry.get_absolute_url }}">{{ entry.title}}</a></h4>
<p>{{ entry.name }}</p>
</div>
</div>
{% endfor %}
</div>
</div>
</section><!-- End Journal Section -->
Now, the user can filter for all blog/journal entries of a category name.