how to display django search result in new page - python

i want to display my django search result on a new html page instead of the page where the search bar is. i have tried manipulating my form tag and it still does'nt redirect to the page when i search, rather it stays on the same page.
index.html
<form action="{% url 'elements:all-elements' %}" method="get">
<input type="text" class="form-control" name="q" value="{{ request.GET.q }}" type="text" placeholder="Search Free Web Elements and Resources">
<button type="submit" class="btn bt-round" ><b><i class="bi bi-search"></i></b></button>
</form>
views.py - this is the view handling the seach, i dont know if anything would be appended there
# Search Function
query = request.GET.get("q")
if query:
vectors = vectors.filter(
Q(title__icontains=query)).distinct()

You can render new template for your search results.
def search(request):
query = request.GET.get("q")
vectors = Model.objects.all()
if query:
vectors = vectors.filter(
Q(title__icontains=query)).distinct()
context = {"vectors":vectors}
return render(request, "template", context)

Related

How to render results from API based on the user's search using Django

As you can see in the picture below I'm trying to have the user search for a given country, start/end date and get the result of "Confirmed Cases" and "Date" back from the API, but I'm not sure how to do it.
I tried using this API, to fill the drop-down menu of the countries -->
https://api.covid19api.com/summary
but this is the other API that I have to use but while changing the parameters for the country and dates -->
https://api.covid19api.com/country/afghanistan/status/confirmed?from=2020-09-06T00:00:00Z&to=2020-09-11T00:00:00Z
Here are snippets of my code:
views.py
def home(request):
# second_response = requests.get('https://api.covid19api.com/country/afghanistan/status/confirmed?from=2020-09-06T00:00:00Z&to=2020-09-11T00:00:00Z').json()
second_response = requests.get('https://api.covid19api.com/summary').json()
my_list = []
for i in range(0, len(second_response['Countries'])):
my_list.append(second_response['Countries'][i]['Country'])
if request.method=='POST':
selected_country = request.POST['selected_country']
print('here', selected_country)
return render(request, 'home.html', {'my_list': my_list})
home.html
<div class="container justify-content-center">
<form action="{% url 'home' %}" method="post">
{% csrf_token %}
<label for="selected_country" style="margin-right: 5px;"> Select a Country, Start & End Dates : </label>
<select name="selected_country" >
{% for object in my_list %}
<option value="">{{object}}</option>
{% endfor %}
</select>
<label for="startdate"></label>
<input type="date" id="startdate">
<label for="enddate"></label>
<input type="date" id="enddate">
<input type="submit" value="Search" />
</form>
</div>
PLUS: when I click on "search" i should get the value of the selected_country because I tried printing it, but it doesn't show for some reason, so the method is post but for some reason I can't get back the selected_country
Any help is appreciated
JAVASCRIPT
if you have any solid grasp of javascript i recommend you do that in javascript, because it will just make it better and easier
otherwise :
view.py
def handler(request):
if request.method=='POST':
selected_country = request.POST['selected_country']
startDate= request.POST['startdate']
endDate= request.POST['enddate']
request_handler = requests.get(f"https://api.covid19api.com/country/{selected_country}/status/confirmed?from={startDate}T00:00:00Z&to={endDate}T00:00:00Z")
if request_handler.status_code=200:
#To prevent errors
request_json=request_handler.json()
else:
pass # do something
return render(request, 'result.html', {"json":request_json})
#you should handle the data at the front end using jinja blocks
note : i don't know much about Django so the code may break

How to create query in django with query in url, and return the filtered result based on the url?

I found several similar answers, but I could not solve the problem (maybe I searched wrong) anyway.
I'm trying to do the following:
Filter a result by getting the value of "q" where is the input containing the value to search
Add the "q" value in the url, like "/search?q=test"
Copy the url above and from there get the filtered result
My problem so far is:
The value of "q" is only added in the url after another search, ie the url contains "q" with the previous search value, which is bad
I can not access the url and have the results filtered, since when I enter this url, a new request object with no value for "q" is created, so I get a ValueError
So far what I've done is:
template
<form method="POST" action="{% url 'blog:post_search' %}?q={{ query }}" class="form-inline">
<div class="md-form my-0">
<input name="q" class="form-control form-control-sm mr-3 w-75" type="text" placeholder="Pesquisar" aria-label="Search">
</div>
<button class="btn btn-outline-white btn-sm my-0" type="submit">GO</button>
{% csrf_token %}
</form>
urls.py
urlpatterns = [
# ....
path('search', views.post_search, name='post_search'),
]
views.py
def post_search(request):
template = "blog/post_search.html"
query = request.POST.get('q')
if query:
posts = Post.objects.filter(title__icontains=query)
else:
posts = Post.objects.all()
context = {'posts': posts, 'query': query}
return render(request, template, context)
You are confusing POST and GET methods here. Query parameters in the url are typically only used with get requests.
So in your form, you can change this:
<form method="POST" action="{% url 'blog:post_search' %}?q={{ query }}" class="form-inline">
to
<form action="{% url 'blog:post_search' %}" class="form-inline">
The default method for a html form is GET, and named inputs will automatically be included in the action url by the browser when you submit the form. So you should not have a querystring in the from action attribute action='/search' is enough.
In the view you access url parameters from request.GET instead of request.POST.
def search(request):
query = request.GET.get('q')

How can I pass values/parameters from HTML to Django Views?

I would usually do this in ajax I think.
But if for example I have a button and a search input box that will have a query value, how can I pass the search value (and possibly multiple values/parameters that is not obtained through a form field) to Django views on button click to the url?
HTML
<div>
<input id="search" name="search" type="text" class="query-search" placeholder="Search...">
<a class="btn btn-primary btn-lg btn-space col-sm-3" href="{% url 'routes_view' %}">View Routes</a>
</div>
Views
def view_detail(request):
...
<How to get values from HTML without using ajax? Or its the only way?>
URLs
url(r'^view/', views.view_detail, name='view_detail')
Understanding from the previous answer, if you do not want the search values to be sent as URL parameters, you can send them via an AJAX POST call and handle that in the view, like this:
<div>
<input id="search" name="search" type="text" class="query-search" placeholder="Search...">
<input onclick="setGetParameter()" type="button" class="btn btn-primary" value = "View Details"/>
</div>
<script>
function setGetParameter(){
var search_word = $("#search").val();
$.ajax({
type: "POST",
url: {% url 'view_detail' %},
data: search_word,
success: function(result){
alert("Success");
}
});
}
</script>
Your view should look something like this.
def search_view(request):
if request.method == "POST":
search_word = request.POST['data']
URL configurations will remain the way other answers describe them.
You can create a HTML form and can submit the form using post method if you do not want to pass values in url.
<div>
<form action="{% url 'view_detail' %}" method="post">
{% csrf_token %}
<input id="search" name="search" type="text" class="query-search"
placeholder="Search...">
<input class="btn btn-primary" type="submit" value="submit">
</form>
</div>
And then in your view you can fetch the data as request.POST.get('search'):
def view_detail(request):
searchWord = request.POST.get('search','')
return HttpResponse(searchWord)
In the same way you can pass multiple parameters.
You can make a button works like a link in your templates, and add the js function on the onclick event, then get the search input value and add the search parameter to the url window.location.href:
<div>
<input id="search" name="search" type="text" class="query-search" placeholder="Search...">
<input onclick="setGetParameter()" type="button" class="btn btn-primary" value = "View Details"/>
</div>
<script>
function setGetParameter(){
searchWord = document.getElementById('search').value;
window.location.href = "{% url 'view_detail' %}" + "?search="+searchWord;
}
</script>
In the views, you can use request.GET.get('search') to get the parameters (search content) you input from the templates, like this:
def view_detail(request):
searchWord = request.GET.get('search')
return HttpResponse(searchWord)
BTW, the urlpatterns is look like this:
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^view$', views.view_detail, name='view_detail'),
]

Django search as input is entered into form

I currently have a working search form in my project that passes through form data to the GET request. Pretty standard.
What I'm wanting to do is search as data is entered into the search form, so that results will display in real time with search data. This is much like what Google does with the instant desktop results. Is this something that's possible with Django?
Below is my current (simple) search
#views.py
def ProductView(request):
title = 'Products'
all_products = Product.objects.all().order_by("product_Name")
query = request.GET.get("q")
if query:
products = all_products.filter(
Q(product_Name__contains=query) |
Q(manufacturer__contains=query)
).distinct()
return render(request, 'mycollection/details.html', { 'all_products' : products })
-
<!-- HTML -->
<!-- SEARCH BAR -->
<form class="navbar-form navbar-left" role="search" method="get" action="{% url 'mycollection:products' %}">
<div class="form-group">
<input type="text" class="form-control" name="q" value="{{ request.GET.q }}">
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
you can save the request.data in to session and if any data is associated with session search data you can put in to value of search box.
request.session['search'] = request.GET.get('q','')
templete :
{% if request.session.search %} {{request.session.search}} {% endif %}

Form-View Mapping Issue in Django

This is becoming very frustrating, like all of my Django form endeavors have been thus far...
I have a search bar form that is supposed to send the user to a url '/project/search/<query>/' and the url works fine if I type in a url but my form is not mapping correctly. I am implementing this first in the search results page, which will still have a search bar, and whenever I type in a value to the search bar I get redirected to '/project/search/'. Where have I gone wrong? I have spent a solid two days on this to no avail.
I am really struggling with this and I have no idea what I am doing wrong. I wish I had at least an error or something to fix but this is just not working.
Here is my form class and view:
from django import forms
class SearchForm(forms.Form):
search_string = forms.CharField(initial='Search Article Text',max_length=100)
def search(request, search_query):
form = SearchForm()
context = RequestContext(request)
search_string = search_query.replace('_',' ')
search_terms = search_query.split('_')
search_results = Article.objects.all()
for term in search_terms:
search_results = search_results.filter(article__icontains=term)
context_dict = {
'search_string':search_string,
'search_results':search_results,
'form':form,
}
if request.method == 'POST':
form = SearchForm(request.POST)
context_dict['form'] = form
if form.is_valid():
search_string = form.cleaned_data['search_string']
search_query = search_string.replace(' ','_')
###return HttpResponseRedirect(reverse('search', args=(search_query,)))
search_url = '/project/search/' + search_query + '/'
return HttpResponseRedirect(search_url)
return render_to_response('search.html', context_dict, context)
The html:
<form action='/beacon/search/' class="navbar-form navbar-right" method='POST'>
<div class="form-group">
{% csrf_token %}
{{ form.search_string }}
</div>
<input type='submit' value='Submit' class='btn btn-default'/>
</form>
I don't really understand your question. You're getting redirected because that's what you've told the view to do: you explicitly return an HttpResponseRedirect. If you don't want to redirect, don't do that.
Ok after troubleshooting for probably 5 or so days I have realized what my issue was (I also had a little help from the Django Users Google group).
I am answering this in case anybody also has my problem in the future btw. I'm obviously not an expert on the forms part of Django.
This all had to do with the actual HTML writeup I had. In my form tag the action was to '/project/search/' which just redirected me to that URL because django thought /project/search/ was different than project/search/query . Therefore all I needed to do for this part was change the action to refer to any URL that would validate my search view- so I picked /project/search/search_query/ but anything after /project/search/ would have worked.
My second issue was with my input. I needed to include a name in my input -'search_string'- so my search view would understand what values the form itself was carrying.
Therefore my html in the end looks like:
<form action='/beacon/search/search_query/' class="navbar-form navbar-right" method='POST'>
<div class="form-group">
{% csrf_token %}
<input type="text" name='search_string' class="form-control" placeholder="Search Article Text"/>
</div>
<!--<button type="submit" class="btn btn-default" value='Submit'>Submit</button>-->
<input type='submit' value='Submit' class='btn btn-default'/>
</form>
Credit to Branko Majic to helping my on Dj Users Group as well. Seriously.

Categories

Resources