python - Django ListView customising queryset -
hopefully should simple 1 me with.
i have page dropdown menu containing 3 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> {% 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 user selects item , hits submit, given results in table generated 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 attempt turn page using pagination controls, queryset resets first (default) item cats, because (i think) form data reset.
any idea how circumvent problem?
thanks!
ps: oh, on note, possible set queryset none begin with? obliged!
update: when use pagination on cats queryset works fine bug displayed on other 2 sets.
to solve problem modified pagination html, accommodate both request form , page number in url string, so:
<div class="pagination"> <span class="page-links"> {% if page_obj.has_previous %} <a href="/browse/?browse={{ input }}&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="/browse/?browse={{ input }}&page={{ page_obj.next_page_number }}">next</a> {% endif %} </span> </div>
the {{ input }} here string containing option submitted via form, e.g. 'cats' or 'worms'.
to able pass template, modified get_context_data method of class based view such:
class browse(generic.listview): template_name = 'app/browse.html' paginate_by = 25 # modifying get_context_data method def get_context_data(self, **kwargs): context = super(browse, self).get_context_data(**kwargs) q = self.request.get.get("browse") context['input'] = q return context 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
that it, url string reads like:
/browse/?browse=cats&page=3
so there is, pagination works alongside method of form.
Comments
Post a Comment