简体   繁体   中英

MultiValueDictKeyError at /search/, Why am I getting this error?

I am very beginner at django, And fall onto this error MultiValueDictKeyError, I've got this error earlier, And I solved it after adding the name tag to HTML file, but this time I am not able to figure it out. please help me fix this error

views.py

from django.shortcuts import render
from .models import Post

# Create your views here.
def main(request):
    return render(request, "blog/index.html", {"Posts":Post.objects.all()})

def viewpost(request, pk):   
    return render(request, "blog/viewpost.html", {"Posts":Post.objects.get(id = pk)})

def search(request):
    if request.method == "GET":
        search = request.GET["search"]
    for post in Post.objects.all():
        if search in post.Title:
            return render(request, "blog/search.html")
        else:
            return render(request, "blog/search.html", {
                "message": "Not Found"
            })

Index.html I am sorry this file is quite too big but its on the third block. I have commented out that block.

{% extends 'blog/layout.html' %}
{% load static %}

{% block body %}
    

    

    <!-- Page Content -->
    <div class="container">

        <div class="row">

        <!-- Blog Entries Column -->
        <div class="col-md-8">

            <h1 class="my-4">Page Heading
            <small>Secondary Text</small>
            </h1>

            <!-- Blog Post -->
            {% for post in Posts %}
                <div class="card mb-4">
                <img class="card-img-top" src="http://placehold.it/750x300" alt="Card image cap">
                <div class="card-body">
                    <h2 class="card-title">{{ post.Title }}</h2>
                    <p class="card-text">{{ post.Description }}</p>
                    <a href="#" class="btn btn-primary">Read More &rarr;</a>
                </div>
                <div class="card-footer text-muted">
                    Posted on {{ post.Date }} by
                    <a href="#">{{ post.Author }}</a>
                </div>
                </div>
            {% endfor %}
            
            <!-- Pagination -->
            <ul class="pagination justify-content-center mb-4">
            <li class="page-item">
                <a class="page-link" href="#">&larr; Older</a>
            </li>
            <li class="page-item disabled">
                <a class="page-link" href="#">Newer &rarr;</a>
            </li>
            </ul>

        </div>

        <!-- Sidebar Widgets Column -->
        <div class="col-md-4">

            **<!-- Search Widget -->
            <div class="card my-4">
            <h5 class="card-header">Search</h5>
            <div class="card-body">
                <form action="{% url 'search' %}" method="GET">
                {% csrf_token %}
                    <div class="input-group">
                    <input type="text" class="form-control" placeholder="Search for..." name="search">
                    <span class="input-group-append">
                        <button class="btn btn-secondary" type="button" ><a href="{% url 'search' %}">Go!</a></button>
                    </span>
                    </div>
                </form>**
            </div>
            </div>

            <!-- Categories Widget -->
            <div class="card my-4">
            <h5 class="card-header">Categories</h5>
            <div class="card-body">
                <div class="row">
                <div class="col-lg-6">
                    <ul class="list-unstyled mb-0">
                    <li>
                        <a href="#">Web Design</a>
                    </li>
                    <li>
                        <a href="#">HTML</a>
                    </li>
                    <li>
                        <a href="#">Freebies</a>
                    </li>
                    </ul>
                </div>
                <div class="col-lg-6">
                    <ul class="list-unstyled mb-0">
                    <li>
                        <a href="#">JavaScript</a>
                    </li>
                    <li>
                        <a href="#">CSS</a>
                    </li>
                    <li>
                        <a href="#">Tutorials</a>
                    </li>
                    </ul>
                </div>
                </div>
            </div>
            </div>

            <!-- Side Widget -->
            <div class="card my-4">
            <h5 class="card-header">Side Widget</h5>
            <div class="card-body">
                You can put anything you want inside of these side widgets. They are easy to use, and feature the new Bootstrap 4 card containers!
            </div>
            </div>

        </div>

        </div>
        <!-- /.row -->

    </div>
    <!-- /.container -->

    
    
    
{% endblock %}

urls.py

from django.urls import path, include
from . import views


urlpatterns = [
    path('',views.main, name = 'main'),
    path('viewpost/<int:pk>/', views.viewpost, name = 'viewpost'),
    path('search/', views.search, name = 'search'),
    
]

search.html

{% extends 'blog/layout.html' %}
{% load static %}

{% block body %}
    <div class="card" style="width: 70vw; margin-left: auto; margin-right: auto; margin-top: 20px; ;">
        <div class="card-body">
        <h2 class="card-title">Search Results:</h2> 
        {% for post in posts %}      
            <h3 class="card-subtitle" style="margin-top: 30px;"><a href="#}" >{{ post.title }}</a></h3>
            <p class="card-text" style="margin-left: 1px;">{{ post.description }}</p>
            <hr>
        {% endfor %}
        </div>
    </div>
    
{% endblock %}

You need to change your views and template like this.

Change button type to submit and you don't need csrf token in the GET request.

  <form action="{% url 'search' %}" method="GET">
  <div class="input-group">
  <input type="text" class="form-control" placeholder="Search for..." name="search">
  <span class="input-group-append">
      <button class="btn btn-secondary" type="submit">Go</button>
  </span>
  </div>
  </form>**
            

Now in the views

First get the search query parameter then filter all the posts containing that query using __icontains and return the results to the template in a context

def search(request): 
    search = request.GET.get ('search', '')
    posts = Post.objects.filter(title__icontains=search)
    return render(request, "blog/search.html", {'posts':posts})
      
            

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM