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 →</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="#">← Older</a>
</li>
<li class="page-item disabled">
<a class="page-link" href="#">Newer →</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.