Reputation: 43
How do I provide a search bar in django? My code is as follows...
home.html
<form method='GET' action="">
<input type="text" name="search" placeholder="Search posts"/>
<input type="submit" value="Search"/>
</form>
views.py
def home(request):
posts = Post.objects.all()
search_term = ''
if 'search' in request.GET:
search_term = request.GET['search']
posts = posts.filter(text__icontains=search_term)
context = {
'posts': posts,
'search-term': search_term
}
return render(request, 'feed/home.html', context)
Upvotes: 0
Views: 7718
Reputation: 121
You likely need a function-based view. This is probably a duplicate or semi-related question.
from django.shortcuts import render
from django.db.models import Q
from .models import Posts #or whatever your model is
def search(request):
query = request.GET.get('q','')
#The empty string handles an empty "request"
if query:
queryset = (Q(text__icontains=query))
#I assume "text" is a field in your model
#i.e., text = model.TextField()
#Use | if searching multiple fields, i.e.,
#queryset = (Q(text__icontains=query))|(Q(other__icontains=query))
results = Posts.objects.filter(queryset).distinct()
else:
results = []
return render(request, 'home.html', {'results':results, 'query':query})
#You can also set context = {'results':results, 'query':query} after
#the else: (same indentation as return statement), and
#use render(request, 'home.html', context) if you prefer.
You should be able come up with your own error-handling or redirects as needed. Your urls.py will probably have to be something like:
from django.urls import path
from . import views
urlpatterns = [
path('feed/', views.search, name='home'),
#'feed/' being the name of desired url, 'views.search' the
#name of your func-based view, and "name='home'" the template
#you're using.
]
And your search bar would prob need to look like:
<form method='GET' action=".">
#I believe lowercase get also works
<input type="text" name="q" placeholder="Search posts"/>
<input type="submit" value="{{ query|escape }}"/>
</form>
EDIT: I forgot that you'll want to access the results and display them in your template (you can drop this in under the form for now). Something like:
{% if query %}
{% if results %}
<ul>
{% for item in results %}
<li>{{ item|escape }}</li>
{% endfor %}
</ul>
{% else %}
<p>Query returned no results.</p>
#SO is formatting "Query" in HTML for some reason. Nonetheless...
{% endif %}
{% endif %}
Upvotes: 8