1

I'm having trouble working with inherited code to make a functional search bar. I've been having the most trouble properly creating a search_results page.

I stripped down my search_results page to having only one line. search_results.html: <div>You searched for {{ query }}</div> but right now, the search_results page doesn't render {{ query }}. No text that the user previously entered appears. All that shows up on that page is "You searched for"

searchbox.html

<form class="search" action="{% url 'search' %}" method='post'>
  {% csrf_token %}
  <input type="search" placeholder="Search here..." name="usr_query" 
      value='{{ query }}' required>
  <button type="submit">Search</button>
</form>

views.py

def search(request):
  query = request.POST['usr_query']
  print "QUERY: "
  print query
  t = loader.get_template('gtr_site/test_search_results.html')
  c = Context({ 'query': query,})
  return HttpResponse(t.render(c))

I was getting a little cautious and added that "print" statement... and it does print out what the user enters in the search bar. But that isn't being generated on my search_results page.

Whats the reasoning for this?

edit:

Adding urls.py

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^about/$', views.about, name='about'),
    url(r'^contact/$', views.contact, name='contact'),
    url(r'^search_engine/$', views.statement_search_engine, name='statement-search') # <- url for searchbox.html,
    url(r'^test_search_results/$', views.search, name='test-search'), # <- url for searchresults.
    url(r'^(?P<statement_id>.+)/$', views.statement_page, name='statement'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Byron Smith
  • 587
  • 10
  • 32

3 Answers3

0

Change value='{{ request.GET.usr_query }}' to value="{{ query }}"

Right now you are forcing it to show the GET parameter. That works on initial page load (which is typically a GET) but at that point you haven't done any searching. You submit the search (properly in my opinion, but it is debatable) as a POST. The search function uses the POST parameter and returns in in context as query, which is correct. But then you display the GET value of usr_query - which does not exist at this point because the page is now a POSTed page. Change the value= and it should work.

  • 1
    Fundamentally disagree about the method. POST requests are for operations that change data on the server. GET is the right method to use for a search, which is about requesting a specific subset of data. Plus, a GET can be bookmarked. – Daniel Roseman Aug 25 '17 at 20:44
  • Thank you for the explanation because I actually don't understand GET and POST as well as I should... this is an inherited project. I've just been keeping things the same as possible. Unfortunately, changing the value attribute to what you stated didn't work. The search_results page still displays nothing. I tried changing to {{ usr_query }} even but... that didn't work. – Byron Smith Aug 25 '17 at 20:46
  • @DanielRoseman As I said, it is debatable. But whichever way you do things, you have to have code, context, template all match. – manassehkatz-Moving 2 Codidact Aug 25 '17 at 20:47
  • @ByronSmith `{{ usr_query }}` won't work with the current code. You need to be mapping from context. Do your debug `print` lines show the query correctly? – manassehkatz-Moving 2 Codidact Aug 25 '17 at 20:50
  • Could any of the code in urls.py be having an effect? – Byron Smith Aug 25 '17 at 21:04
  • @ByronSmith I just noticed you labeled the code above `searchbox.html` but in the template function it is is `test_search_results.html` - if you actually have 2 different files, that would explain everything. Make sure you are updating `test_search_results.html` with the correct context query reference. – manassehkatz-Moving 2 Codidact Aug 25 '17 at 21:12
  • - There is no file called searchbox.html. That file is actually called "search_engine.html", and it only displays the page with the search box for the user to type into. - test_search_results.html, however, is supposed to be the search results template. I would think that it _is getting the correct context query reference_ because the `search` function is what runs when test_search_results.html is requested. I'm going to include urls because it's possible I might be calling the search function incorrectly or something like that. – Byron Smith Aug 25 '17 at 21:19
  • @manassehkatz I added a print statement to print out the `c`, which holds whatever is returned by the Context function. It prints out a blank line. But the print statement for the query remains (isn't a blank line) – Byron Smith Aug 25 '17 at 21:35
0

Short answer:

Seems like this slipped by:

c = Context({ 'query': query,})

This is in views.py. Context() doesn't cause any error messages but... In order to get the functinality I needed, all I had to do was remove this function and make the c variable a regular dictionary.

I included the Context function because of this stackoverflow question Writing a very basic search form in Django

Byron Smith
  • 587
  • 10
  • 32
  • I never use the Context() function myself but I looked it up and it seemed that you were using it correctly. But note that if you didn't change `{{ request.GET.usr_query }}` to `{{ query }}` it still wouldn't be working. – manassehkatz-Moving 2 Codidact Aug 25 '17 at 22:22
0

Your Searchbox.html method is a 'post' instead of a 'get'

<form class="search" action="{% url 'search' %}" method='get'>
     {% csrf_token %}
     <input type="search" placeholder="Search here..." name="usr_query" 
        value='{{ query }}' required>
     <button type="submit">Search</button>
</form>

views.py

class search(ListView):
    model = YourModel #The model model you want to search
    template_name = 'gtr_site/test_search_results.html'


    def get_queryset(self):
   
        query = self.request.GET.get('usr_query')
        object_list = YourModel.objects.filter(modelfield__icontains=query)
        return object_list

The in your webpage probably index.html you should add the return.

  {% for result in object_list %} 
    {{ result.name }}   
  {% endfor %}
Oreximena
  • 131
  • 1
  • 9