Hopefully this should be a simple one to help me with.
I have a page with a dropdown menu containing three items:
<form method="GET">
<select name="browse">
<option>Cats</option>
<option>Dogs</option>
<option>Worms</option>
</select>
<input type="submit" value="Submit" />
</form>
<!-- Output table -->
<table id="myTable">
<thead>
<tr>
<th>Name</th>
<th>Colour</th>
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
<td>{{ object.name }}</td>
<td>{{ object.colour }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Pagination controls -->
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
{% endif %}
</span>
</div>
When the user selects an item and hits submit, they are given the results in a table as generated by the generic ListView:
class Browse(generic.ListView):
template_name = 'app/browse.html'
paginate_by = 25
def get_queryset(self):
queryset = Cats.objects.all()
if self.request.GET.get("browse"):
selection = self.request.GET.get("browse")
if selection == "Cats":
queryset = Cats.objects.all()
elif selection == "Dogs":
queryset = Dogs.objects.all()
elif selection == "Worms":
queryset = Worms.objects.all()
else:
queryset = Cats.objects.all()
return queryset
However, when I attempt to turn a page using the pagination controls, the queryset resets to the first (default) item Cats, because (I think) the form data is reset.
Any idea how to circumvent this problem?
Thanks!
PS: Oh, on that note, is it possible to set the queryset to none to begin with? Much obliged!
UPDATE: When I use pagination on the Cats queryset it works fine so the bug is only displayed on the other two sets.
To solve this problem I just modified the pagination HTML, to accommodate both the get request from the form and the page number in the url string, like so:
The {{ input }} here is a string containing the option submitted via the form, e.g. 'Cats' or 'Worms'.
To be able to pass this into the template, I modified the get_context_data method of the class based view as such:
That was it, the url string now reads something like:
So there it is, pagination now works alongside the get method of the form.
I put together a template tag to help using queries based on Sirrah's answer. Example:
If query params is a dictionary
{'foo': 'bar'}
passed in the context, it will be rendered to something like this:Syntax:
Variables can be lists, dicts, strings or None (None is skipped).
Code: