Reputation: 715
I have an existing HTML form (text field + button) but have no idea how to pass an input value to a list view.
Update:
book/home.html:
<form class="form-inline my-2 my-lg-0" method="get" action="{% url 'book:search' %}">{% csrf_token %}
<input style="font-size: 12px; width: 200px" class="form-control mr-sm-2" name="search" type="search" placeholder="Book Name" aria-label="Search">
<button class="btn btn-outline-primary my-2 my-sm-0" type="submit">Search</button>
</form>
book/models:
class Book(models.Model):
title = models.CharField(max_length=191, unique=True)
slug = models.SlugField(unique=True, null=True, allow_unicode=True)
pub_date = models.DateField()
............
book/views:
class SearchResultView(generic.ListView):
template_name = 'book/search.html'
model = Book
paginate_by = 10
def get_queryset(self):
queryset = super().get_queryset()
search = self.request.GET.get('search')
if search:
queryset.filter(title__icontains=search)
return queryset
class BookDetailView(generic.DetailView):
template_name = 'book/detail.html'
model = Book
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['all_categories'] = Category.objects.all()
return context
book/urls:
app_name = 'book'
urlpatterns = [
path('', views.HomePageView.as_view(), name='home'),
path('<slug:slug>/', views.BookDetailView.as_view(), name='detail'),
path('search/', views.SearchResultView.as_view(), name='search')
]
book/templates/search.html (just for testing):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1> here we go </h1>
</body>
</html>
Upvotes: 0
Views: 541
Reputation: 1110
If you are trying to create a custom queryset and show only the filter queryset instead of the full one, you can overwrite the get_queryset()
function and get the form input by accessing self.request.POST
.
def get_queryset(self):
if self.request.method == 'POST':
book_name = self.request.POST.get('book_name', '')
return Book.objects.filter(name=book_name) # i'm assuming that in your Book model the name field if called 'name'
Then, you just have to be sure that the input has a name like this:
<input name="book_name" style="font-size: 12px; width: 200px" class="form-control mr-sm-2" type="search" placeholder="Book Name" aria-label="Search">
Upvotes: 0
Reputation: 47354
First of all for search functionality you can use GET
request instead of POST
. To send form data to the specific view use action
attribute. Also you need to add name
attribute for input
element:
<form class="form-inline my-2 my-lg-0" method="get" action="{% url 'view_urlname' %}">
<input style="font-size: 12px; width: 200px" class="form-control mr-sm-2" type="search" placeholder="Book Name" name="search" aria-label="Search">
<button class="btn btn-outline-primary my-2 my-sm-0" type="submit">Search</button>
</form>
To fetch form data in the view use self.request.GET
:
class SearchResultView(generic.ListView):
template_name = 'book/search.html'
model = Book
paginate_by = 100
def get_queryset(self):
queryset = super().get_queryset()
search = self.request.GET.get('search')
if search:
queryset.filter(filedname_contains=search)
return queryset
Upvotes: 1