Django Portfolio Journal

Filter the Journal page


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. 


Designed by BootstrapMade and modified by DoriDoro