Writing a very basic search form in Django - python

So I'm trying to get something very simple accomplished. I want to enter a term into my search box, and display it on the resulting page.
My HTML for the form is
<form method="get" action="/results/" class="navbar-form pull-right">
<input type="text" id="searchBox" class="input-medium search-query" name="q" placeholder="Search">
<input type="submit" class="btn" value="Search" >
</form>
The views.py looks like this:
def search(request):
query = request.GET['q']
t = loader.get_template('template/results.html')
c = Context({ 'query': query,})
return HttpResponse(t.render(c))
And finally the result template contains:
<div>You searched for: {{ query }} </div>
Here's the urls.py
urlpatterns = patterns('',
url(r'^home/$', 'search.views.home'),
url(r'^results/$', 'search.views.results'),
Nothing is showing up in the {{ query }} space.

Ok so the action handling the search in your views.py is supposed to be search but as I suspected in your urls.py you don't call the search method anywhere.
Where do you execute search method?
Urls should be like this:
urlpatterns = patterns('',
url(r'^home/$', 'search.views.home'),
url(r'^results/$', 'search.views.search'),
# or at least have a url for the search view
Note the action attribute in your form
It is action="/results/". This means result view is the one who is supposed to be handling the form. You may also change this to action="/search/" and have your urls like this:
urlpatterns = patterns('',
url(r'^home/$', 'search.views.home'),
url(r'^results/$', 'search.views.results'),
url(r'^search/$', 'search.views.search'),

Related

Django Parameters in URL from POST Request

I'm trying to create a search bar in Django, where users can enter a value to search for, click enter / search button, and then the url redirects to https:localhost:3000/usearch/abc, if they for example search for abc. This is URL paramter can always change based on the search, and it should send the parameter to the views.py file to be processed, though I can't get it to work.
urls.py
urlpatterns = [
path('', views.index, name='index'),
path('register/', views.register, name='register'),
path('usearch/', views.usearch, name='usearch'),
path('usearch/<str:query>', views.usearch_query, name='usearch_query'
]
views.py
def usearch(request):
return render(request, 'myapp/usearch.html')
def usearch_query(request, query):
context = {'query': query}
print(query) # Testing the search result
return render(request, 'myapp/usearch_query.html'}
usearch.html
<form method="GET" action="{% url 'usearch_query' %}
<input type="search" placeholder="Search here...">
<button type="submit"> Search </button>
</form>
usearch_query.html
{{ query }}
I essentially want the user to search something, have it navigate to usearch/<search_parameter> and process the search in the usearch_query function so I can do some computations with it.

django: Take table name as input from user and show the content of the table from database

I am trying to implement form in django, where I will take input from user, e.g, its table name and then I want to show all the content on the webpage. So, far I tried below code.
views.py
from django.shortcuts import render
# Create your views here.
from django.shortcuts import HttpResponse
from .models import my_custom_sql
from django.core.exceptions import *
def index(request):
return render(request, 'forms_spy/form.html')
def search(request):
if request.method == 'POST':
search_id = request.POST.get('textfield', None)
try:
webpages_list = my_custom_sql.objects.get(name = search_id)
data_list = {'access_record':webpages_list}
return render(request,'forms_spy/index.html', context=data_list)
except my_custom_sql.DoesNotExist:
return HttpResponse("no such user")
else:
return render(request, 'forms_spy/form.html')
forms_spy/models.py
from django.db import models
# Create your models here.
def my_custom_sql(TABLE):
with connections["my_oracle"].cursor() as cursor:
cursor.execute("SELECT * FROM {};".format(TABLE))
row = cursor.fetchall()
return row
templates/forms_spy/form.html
<form method="POST" action="/search">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>
urls.py under project folder:
from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from forms_spy.views import *
urlpatterns = [
# url(r'^$', views.index, name='index'),
#url(r'^', include('livefleet.urls', namespace='livefleet')),
path('admin/', admin.site.urls),
url(r'^search/', search),
url(r'^index/', index),
]
I referred to this link. When I entered the value getting below error.
RuntimeError at /search
You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to 127.0.0.1:8000/search/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.
change in urls.py
from
url(r'^search/', search),
to
url(r'^search/', search, name='search'),
<form method="POST" action="{% url 'search' %}">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>
ur url is search/ , so u need to put the same in the form action
change urls to
path('search/', search)
slash character for dynamic route, example call in browser (http://domain/search) or (http://domain/search/) if you using both it's work.
templates
<form method="POST" action="/search/">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>

NoReverseMatch at URL

I've been trying to create a movie survey in Django for an assignment, and I am currently working on the function. I can't seem to understand why won't it recognize the URL I pass.
I tried removing the hardcoded URL as shown in the Django tutorial on the framework's site, but that doesn't make the error go away.
Here's an excerpt from urls.py:
urlpatterns = [
url(r'^$', views.index, name="index"),
path('movie=<int:movie_id>&user=<int:user_id>/', views.movie, name='movie'),
path('ratings/', views.ratings, name='movie'),
path('rating/<int:movie_id>/', views.rating, name='movie'),
path('movie=<int:movie_id>&user=<int:user_id>/vote/', views.vote, name='vote'),
path('register/',views.register, name='register'),
]
This is my movie view( supposed to present a movie and a star rating radio for the user to rate the movie), where the URL is constructed and passed to HTML:
def movie(request,movie_id,user_id):
movie = get_object_or_404(Movie, pk=movie_id)
voteURL = '/polls/movie=' + str(movie_id) + '&user='+str(user_id)+'/vote/'
context = {
'mymoviecaption':movie.Title,
'moviePoster': 'https://image.tmdb.org/t/p/original'+tmdb.Movies(movie.TMDBID).images().get('posters')[0].get('file_path'),
'myrange': range(10,0,-1),
'myuserid':user_id,
'voteurl': voteURL,
'mymovieid':movie_id
}
#print(nextURL)
translation.activate('en')
return HttpResponse(render(request, 'movieview.html', context=context))
The HTML excerpt, where the vote view is called:
<form action="{% url voteurl %}" method="post">
{% for i in myrange %}
<input id="star-{{i}}" type="radio" name="rating" value={{i}}>
<label for="star-{{i}}" title="{{i}} stars">
<i class="active fa fa-star" aria-hidden="true"></i>
</label>
{% endfor %}
<input type="submit">Vote!</input>
</form>
The vote view( should save to database and redirect to the next movie, doesn't save to database yet, because I didn't want to clutter it with records until I am sure I got the function to work):
def vote(request, movie_id,user_id):
try:
nextmovie=get_object_or_404(Movie, pk=movie_id+1)
nextURL = '/polls/movie=' + str(movie_id + 1) + '&user='+str(user_id)+'/'
except Http404:
nextURL = '/polls/ratings'
try:
myrating = int(request.POST['rating'])
print(myrating)
except:
# Redisplay the question voting form.
return render(request, '/polls/movie=' + str(movie_id + 1) + '&user='+str(user_id)+'/', {
'error_message': "You didn't select a choice.",
})
return HttpResponseRedirect(nextURL)
No matter what I try, I get the NoReverseMatch at /polls/movie=1&user=9/ whenever I try to load the first movie page, despite said URL being defined in urlpatterns.
This is not the way how you provide two pk in the urls
It should be like this
path('movie/<int:movie_id>/<int:user_id>/', views.movie, name='movie'),
Also this is not the way of providing url in the template so it should be something like this
<form action="{% url 'vote' %}" method="post">
# {% url 'url_name' %}
# if app_name provided {% url 'app_name:url_name' %}
And please follow the tutorials step by step

Django, creating a functional search bar and search results page

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)
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.
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
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 %}

NoReverseMatch during render

I'm receiving this error:
NoReverseMatch at /comments_page/1/post_comment/
Reverse for 'post_comment' with arguments '('',)' not found. 1 pattern(s) tried: ['comments_page/(?P[0-9]+)/post_comment/$']
My views.py
def post_comment(request, product_id):
host_product = Product.objects.get(pk=product_id)
comment = Comment()
comment.product = host_product
comment.author = request.POST["author"]
comment.comment_text = request.POST["comment"]
comment.save()
return render(request, 'comments_page/detail.html', {"host_product": host_product})
My comments_page\urls.py
from django.conf.urls import url
from . import views
app_name = "comments_page"
urlpatterns = [
# /comments_page/
url(r'^$', views.index, name="index"),
# /comments_page/1/
url(r'^(?P<product_id>[0-9]+)/$', views.detail, name="detail"),
# /comments_page/1/post_comment/
url(r'^(?P<product_id>[0-9]+)/post_comment/$', views.post_comment, name='post_comment'),]
My detail.html
<form action="{% url 'comments_page:post_comment' product.id %}" method="post">
{% csrf_token %}
Name: <input type="text" id="author" name="author">
Comment:
<textarea id="comment" name="comment"></textarea><br>
<input type="submit" value="Post Comment">
I think I've identified the problem as being in the product.id here
{% url 'comments_page:post_comment' product.id %}
in the html page. I've tried formatting this a couple of different ways, but I haven't had any luck. Do note, the comment is going through and the form and it works as far as updating the database and loading the entry on the page goes, but the page is not being redirected. I have to reload it manually. Any help would be appreciated.
The error message shows that the argument you pass to the {% url %} tag does not exist and resolves to an empty string. Your view indeed does not pass in a product variable, only a host_product variable. You need to change the tag accordingly:
{% url 'comments_page:post_comment' host_product.id %}
For those who may wonder, the fix is to change the return function in views.py to this
return render(request, 'comments_page/detail.html', {"product": host_product})
I do not understand why this works, but it does. Any suggestions as to how to clean up my post_comment function would be appreciated. I feel it's overly convoluted by using host_product

Categories

Resources