West
West

Reputation: 2570

How to include a search form in an existing page in django?

I have a function called search in views.py which I use to process search parameters and display results on a different page. My search form is on the home page template so that I can search from there and be redirected to the page specified by my search function. Currently my views.py looks like this:

from django.shortcuts import render
from django.views.generic import ListView
from django.core.paginator import Paginator
from core.models import Movie
from core.documents import MovieDocument


class MovieList(ListView):
    model = Movie   
    template_name='movie_list.html' 
    paginate_by = 10
    queryset = Movie.objects.all() 


def search(request):

    q = request.GET.get('q')

    if q:
        movies = MovieDocument.search().query("match", title=q)
    else:
        movies = ''

    return render(request, 'search.html', {'movies': movies}) 

The home page is being served by the MovieList class and I have the following html snippet for the search field in the home page movie_list.html:

<form method="get" action="{{ views.search}}">
<input id="q" name="q" type="text" placeholder="Search...">
</form>

The url path for MovieList looks like this: path('movies',views.MovieList.as_view(),name='MovieList')

When,for example I type 'terminator' in the search box, the url in the browser changes to http://127.0.0.1:8000/movies?q=terminator but the search function is not called and nothing happens. How can I get this working properly, preferably without having to define a new url to capture the search query string but by specifying the search function in the form's action attribute, unless that's not possible? Having the search box on its own page and creating its own url path actually works but that's not what I need.

Upvotes: 0

Views: 841

Answers (2)

West
West

Reputation: 2570

Ok so I finally figured this out, quite simple. All I had to do was add a path for redirecting the search to a new page:

path('search',views.search,name='search')

Then I updated the form tag: <form method="get" action="{% url 'search' %}">

It doesn't matter what the names are in the path arguments as long as you are pointing to the correct view function and the form's action is matched to the correct url name.

Upvotes: 0

Manzurul Hoque Rumi
Manzurul Hoque Rumi

Reputation: 3094

You can't add views.search directly in form action.

Update your view like this:

class MovieList(ListView):
    model = Movie   
    template_name='movie_list.html' 
    paginate_by = 10
    queryset = Movie.objects.all()
    show_search = False

    def get(self, request, *args, **kwargs):
        if self.show_search == True:
            template_name='search.html'
        else:
            template_name='movie_list.html'
        context = self.get_context_data()
        return self.render_to_response(context)
    def get_queryset(self):
        try:
            q = self.kwargs['q']
        except:
            q = ''
        if (q != ''):
            object_list = self.model.search().query("match", title=q)
            self.show_search = True
        else:
            self.show_search = False
            object_list = self.model.objects.all()
        return object_list

Upvotes: 1

Related Questions