Kategoriefilterung und Stichwortsuche
In diesem Kapitel lernst du, URL-Query-Parameter zu verarbeiten, eine Kategoriefilter-Navigation zu implementieren und eine Stichwortsuchfunktion.
URL-Query-Parameter
Query-Parameter sind der Teil der URL nach dem Fragezeichen, wie zum Beispiel/?category=django&q=入门。
Verwenden Sie in Django-View-Funktionenrequest.GETDiese Parameter abrufen.
Beispiel
# request.GET ist ein wörterbuchähnliches Objekt
# .get('key', 'Default value') ruft den Parameter sicher ab, gibt den Standardwert zurück, wenn er nicht existiert
category_slug = request.GET.get('category', '') # Kategoriefilter
keyword = request.GET.get('q', '') # Suchbegriffe
print(f'Kategorie: {category_slug}, Suche: {keyword}')
Verkettete ORM-Filterung und Q-Objekte
Filtern und Suchen erfordern das dynamische Zusammenstellen von Abfragebedingungen.
Beispiel
from django.shortcuts import render
from django.db.models import Q # Q-Objekte werden verwendet, um komplexe Abfragebedingungen zu kombinieren.
from .models import Post, Category
def index(request):
"""Blog-Startseite: Artikelliste anzeigen, Kategoriefilterung + Stichwortsuche unterstützen"""
posts = Post.objects.all().order_by('-created_at')
# 1. Abfrageparameter abrufen
category_slug = request.GET.get('category', '')
keyword = request.GET.get('q', '')
# 2. Nach Kategorie filtern
if category_slug:
# category__slug: Zugriff auf das slug-Feld der Kategorie-Tabelle über den Fremdschlüssel (doppelter Unterstrich)
posts = posts.filter(category__slug=category_slug)
# 3. Nach Stichwort suchen (Titel oder Zusammenfassung)
if keyword:
# Q(title__icontains=...) | Q(summary__icontains=...): ODER-Kombination
# icontains: Groß-/Kleinschreibung-unabhängige Enthält-Abfrage
posts = posts.filter(
Q(title__icontains=keyword) | Q(summary__icontains=keyword)
)
# 4. Alle Kategorien abrufen (zum Rendern der Filter-Navigation)
categories = Category.objects.all()
context = {
'posts': posts,
'categories': categories,
'category_slug': category_slug, # Wird an das Template übergeben, um die aktuelle Auswahl hervorzuheben
'keyword': keyword, # Suchbegriffe ausgeben
'title': 'EXAMPLE Blog - Startseite',
}
return render(request, 'blog/index.html', context)
Erklärung der ORM-Abfragemethoden
| Methoden | Bedeutung | Beispiel |
|---|---|---|
field__exact | Exakte Übereinstimmung | title__exact='Django' |
field__iexact | Exakte Übereinstimmung ohne Berücksichtigung der Groß-/Kleinschreibung | title__iexact='django' |
field__contains | Enthält (Groß-/Kleinschreibung beachtend) | title__contains='入门' |
field__icontains | Enthält (Groß-/Kleinschreibung nicht beachtend) | title__icontains='django' |
field__gte / lte | Größer oder gleich / Kleiner oder gleich | created_at__gte='2024-01-01' |
field__in=[...] | In der Liste | category__in=[1, 2, 3] |
Doppelter Unterstrich
__ist eine Kernkonvention des Django ORM: wird verwendet, um auf Felder verknüpfter Modelle zuzugreifen oder anzugeben, wie Felder abgefragt werden. Zum Beispielcategory__slugsteht für das Überqueren des Fremdschlüssels zum slug-Feld der Category-Tabelle.
Homepage-Template aktualisieren
Fügen Sie eine Kategoriefilternavigation und ein Suchfeld über der Artikelliste hinzu.
Beispiel
{% extends 'blog/base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h2 class="section-title">Neueste Artikel</h2>
<!-- Suchfeld -->
<div class="search-bar">
<!-- Formular method="get":Übermittelte Parameter erscheinen in der URL(/search/?q=xxx) -->
<form method="get" action="{% url 'index' %}">
<input
type="text"
name="q"
value="{{ keyword }}"
placeholder=Nach Artikeltiteln oder Zusammenfassungen suchen...
class="search-input"
/>
{% if keyword %}
<a href="{% url 'index' %}" class="clear-btn">✕</a>
{% endif %}
</Form>
</div>
<!-- Kategoriefilter-Navigation -->
<div class="category-bar">
<!-- 'Alle'-Schaltfläche: ohne Kategorieparameter -->
<a href="{% url 'index' %}"
class="{% if not category_slug %}active{% endif %}">Alle</a>
{% for cat in categories %}
<a href="{% url 'index' %}?category={{ cat.slug }}{% if keyword %}&q={{ keyword }}{% endif %}"
class="{% if category_slug == cat.slug %}active{% endif %}">
{{ cat.name }}
</a>
{% endfor %}
</div>
<!-- Filterergebnisstatistik -->
<p class="result-info">
Insgesamt {{ posts.count }} Beiträge
{% if keyword %}, Suche nach "{{ keyword }}"{% endif %}
</p>
{% if posts %}
<div class="article-grid">
{% for post in posts %}
<a href="{% url 'post_detail' post.pk %}" class="card-link">
<div class="article-card">
<div class="card-content">
<span class="card-category">{{ post.category.name }}</span>
<h3>{{ post.title }}</h3>
<p>{{ post.summary|truncatechars:80 }}</p>
<span class="card-date">{{ post.created_at|date:"Y-m-d" }}</span>
</div>
</div>
</a>
{% endfor %}
</div>
{% else %}
<p class="empty-tip">Keine passenden Artikel gefunden</p>
{% endif %}
{% endblock %}
Stile für Filter-Navigation und Suchfeld
Beispiel
.search-bar {
margin-bottom: 20px;
}
.search-input {
width: 100%;
padding: 12px 16px;
border: 2px solid #eee;
border-radius: 8px;
font-size: 15px;
outline: none;
transition: border-color 0.2s;
}
.search-input:focus {
border-color: #2c3e50;
}
.clear-btn {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
color: #999;
text-decoration: none;
font-size: 18px;
}
.category-bar {
display: flex;
gap: 10px;
margin-bottom: 16px;
flex-wrap: wrap;
}
.category-bar a {
padding: 6px 16px;
border: 1px solid #ddd;
border-radius: 20px;
text-decoration: none;
color: #333;
font-size: 14px;
transition: all 0.2s;
}
.category-bar a.active {
background: #2c3e50;
color: #fff;
border-color: #2c3e50;
}
.category-bar a:hover {
border-color: #2c3e50;
}
.result-info {
color: #999;
font-size: 14px;
margin-bottom: 16px;
}
.card-link {
text-decoration: none;
color: inherit;
}
Auch die Links der Kategorie-Schaltflächen behalten
categoryundkeywordParameter:?category={{ cat.slug }}&q={{ keyword }}. Auf diese Weise geht die Suchbedingung nicht verloren, wenn Benutzer zuerst suchen und dann auf eine Kategorie klicken, und beide Bedingungen wirken gleichzeitig.
Praxis: Filterung und Suche testen
Starten Sie den Server und überprüfen Sie die folgenden Punkte:
- Klicken Sie auf die Kategorie-Schaltfläche, um nur Artikel der entsprechenden Kategorie anzuzeigen.
- Geben Sie Schlüsselwörter ein, um Titel und Zusammenfassungen in Echtzeit zu filtern.
- Kategorie + Suche kombinieren: Gefilterte Ergebnisse erfüllen beide Bedingungen gleichzeitig
- Die Schaltfläche „Alle“ löscht den Kategoriefilter und stellt die Anzeige aller Artikel wieder her.
Kapitelzusammenfassung
In diesem Kapitel hast du die Methoden zum Umgang mit URL-Abfrageparametern in Django gemeistert: mit request.GET.get() Parameter abrufen, ORM-verkettete Filterung + Q-Objekte zum Implementieren komplexer Abfragen und dynamisches Verketten von URL-Parametern in Templates zum Implementieren von Filterlinks.
Kategoriefilterung und Suchfunktion ermöglichen es Benutzern, schnell interessante Artikel zu finden.
Weitere Erweiterungen