Personal Catalogue: Django & PostgreSQL — Chapter 6, Exercise 1 ==================================================== TASK Add the tag-filtering logic to ItemListView, make tags clickable in the list template, and confirm visiting /?tag=python shows only items actually tagged Python. SOLUTION 1. catalogue/views.py — update ItemListView with the get_queryset() and get_context_data() overrides from the chapter: class ItemListView(ListView): model = Item template_name = 'catalogue/item_list.html' context_object_name = 'items' paginate_by = 25 def get_queryset(self): queryset = Item.objects.select_related('item_type').prefetch_related('tags') tag_name = self.request.GET.get('tag') if tag_name: queryset = queryset.filter(tags__name=tag_name) return queryset def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['active_tag'] = self.request.GET.get('tag', '') return context 2. catalogue/templates/catalogue/item_list.html — inside the item loop, render each tag as a link: {% for tag in item.tags.all %} #{{ tag.name }} {% endfor %} And above the list, show the active filter with a way to clear it: {% if active_tag %}
Filtered by: #{{ active_tag }} (clear)
{% endif %} CONFIRMING IT WORKS Ensure at least one real item (from earlier chapters) is tagged "Python", then visit the root URL with the query string /?tag=python directly, or click a rendered "#Python" link from an item that carries it. The list should now show only items actually tagged Python, with the "Filtered by: #Python (clear)" banner visible, and clicking "(clear)" should return to the full, unfiltered list. WHY THIS WORKS AS AN ANSWER ---------------------------- It implements the filtering exactly as specified (reading the query parameter, filtering via the ORM's own tags__name lookup), and verifies the result both by direct URL and by using the clickable link the template itself now produces, confirming the whole loop works end to end.