Abhay Raghuvanshi
Abhay Raghuvanshi

Reputation: 131

how to make a search in post (in django)

I am working on making a search form in the website through which we can search for a particular blog title till now I have created a form:

<form action="GET" action="{% url 'posts:search' %}">
    <input name="q" type="text" placeholder="Search" value="{{ request.GET.q }}">
    <input type="submit">
</form>

url for that in urls.py:

url(r'^results/$', views.search, name='search'),

function under views.py:

def search(request):
  query = request.GET.get('q')
  posts = Posts.objects.filter(Q(title__icontains=query))
  return render(request, 'posts/posts.html', {'posts': posts})

Whenever I click on search button it goes to the URL http://127.0.0.1:8000/GET/?q=lots+of and gives the error Posts matching query does not exist.

traceback for the error:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/GET/?q=lots+of

Django Version: 2.0.5
Python Version: 3.6.5
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'posts']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



  Traceback:

  File "C:\Users\Fruity_Dude\AppData\Local\Programs\Python\Python36\lib\site- 
  packages\django\core\handlers\exception.py" in inner
  35.             response = get_response(request)

  File "C:\Users\Fruity_Dude\AppData\Local\Programs\Python\Python36\lib\site- 
  packages\django\core\handlers\base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, 
  request)

  File "C:\Users\Fruity_Dude\AppData\Local\Programs\Python\Python36\lib\site- 
  packages\django\core\handlers\base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, 
  **callback_kwargs)

  File "C:\Users\Fruity_Dude\Projects\Django\devflow\posts\views.py" in 
  post_details
  17.   posts = Posts.objects.get(slug=slug)

  File "C:\Users\Fruity_Dude\AppData\Local\Programs\Python\Python36\lib\site- 
  packages\django\db\models\manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, 
  **kwargs)

  File "C:\Users\Fruity_Dude\AppData\Local\Programs\Python\Python36\lib\site- 
  packages\django\db\models\query.py" in get
  403.                 self.model._meta.object_name

  Exception Type: DoesNotExist at /GET/
  Exception Value: Posts matching query does not exist.

Upvotes: 0

Views: 2335

Answers (1)

Alasdair
Alasdair

Reputation: 309029

You are submitting the form to the wrong URL http://127.0.0.1:8000/GET/?q=lots+of because you have action="GET".

<form action="GET" action="{% url 'posts:search' %}">

Change it to method="GET":

<form method="GET" action="{% url 'posts:search' %}">

The error message shows that your post_details view cannot handle the case where a post with that slug does not exist:

def post_details(request, slug)
    posts = Posts.objects.get(slug=slug)  # can raise DoesNotExist
    ...

You could use get_object_or_404 instead:

from django.shortcuts import get_object_or_404

def post_details(request, slug)
    posts = get_object_or_404(Posts, slug=slug)
    ...

Finally, I would recommend renaming your model from Posts to Post to match the recommended Django style, and use post = get_object_or_404(...) since you are fetching a single post.

Upvotes: 3

Related Questions