modifier la valeur de paginate_by pour toutes les pages
J'ai une question complémentaire sur la réponse à Modifier la valeur de paginate_by à la volée
J'ai ajouté ce qui suit dans le HTML
<form method="GET">
<select name="paginate_by" id="">
<option value="5">5</option>
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
</select>
<input type="submit" value="Paginate">
</form>
et cette fonction dans ma ListView
classe
class ReviewPostListView(ListView):
model = Reviews
template_name = 'reviews/reviews.html'
context_object_name = 'rows'
ordering = ['id']
paginate_by = 5
def get_paginate_by(self, queryset):
return self.request.GET.get("paginate_by", self.paginate_by)
cela fonctionne très bien et le paginate_by
est ajouté à l'URL. Mon problème est que lorsque je clique sur la deuxième page, cela revient à 5.
Ceci est ma pagination HTML
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?page=1">First</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="?page={{ num }}">{{num}}</a>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a class="btn btn-outline-info mb-4" href="?page={{ num }}">{{num}}</a>
{% endif %}
{% endfor %}
{%if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?page={{page_obj.next_page_number}}">Next</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.paginator.num_pages }}">Last</a>
{% endif %}
{% endif %}
Quel est le principe de garder le paramètre paginate_by (s'il existe) dans l'URL lors d'une boucle sur les pages?
Réponses
En utilisant {{ request.GET.paginate_by }}
, vous pouvez accéder aux paginate_by
paramètres de requête dans votre modèle.
Ainsi, votre HTML de pagination ressemblera à:
{% if is_paginated %}
{% firstof request.GET.paginate_by "5" as paginate_by %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?page=1&paginate_by={{ paginate_by }}">First</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="?page={{ num }}">{{num}}</a>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a class="btn btn-outline-info mb-4" href="?page={{ num }}">{{num}}</a>
{% endif %}
{% endfor %}
{%if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?page={{page_obj.next_page_number}}&paginate_by={{ paginate_by }}">Next</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.paginator.num_pages }}&paginate_by={{ paginate_by }}">Last</a>
{% endif %}
{% endif %}
firstof
is définira la valeur de paginate_by
sur le paramètre de requête ou 5
, qui sera la valeur par défaut.
Vous pouvez créer une balise de modèle qui gérera les paramètres de requête pour vous.
Voici deux balises simples
@register.simple_tag(takes_context=True)
def add_get_param(context, **kwargs):
"Used to add/replace query parameters to the current URL."
params = context["request"].GET.dict()
params.update(kwargs)
return "?{}".format(urlencode(params))
@register.simple_tag(takes_context=True)
def remove_get_param(context, *args):
"Used to remove query parameters from the current URL."
params = context["request"].GET.dict()
for key in args:
params.pop(key, None)
return "?{}".format(urlencode(params))
Et votre HTML ressemblera à
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?paginate_by={% add_get_param page=1 %}">First</a>
<a class="btn btn-outline-info mb-4" href="{% add_get_param page=page_obj.previous_page_number %}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="{% add_get_param page=num %}">{{num}}</a>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a class="btn btn-outline-info mb-4" href="?paginate_by={{ paginate_by}}&page={{ num }}">{{num}}</a>
{% endif %}
{% endfor %}
{%if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="{% add_get_param page=page_obj.next_page_number %}">Next</a>
<a class="btn btn-outline-info mb-4" href="{% add_get_param page={{ page_obj.paginator.num_pages %}">Last</a>
{% endif %}
{% endif %}
Avec cela, tout ce qui était déjà présent dans les paramètres de requête continuera d'être là, seule la page sera modifiée. Cela fonctionne donc si vous décidez d'ajouter plus de paramètres comme pour le filtrage.
Vous pouvez essayer ceci dans votre modèle HTML:
<select name="paginate_by" onchange="location = this.value;">
<option value="">select</option>
<option value="?paginate_by=5&{{page_obj.number}}">5</option>
<option value="?paginate_by=10&{{page_obj.number}}">10</option>
<option value="?paginate_by=20&{{page_obj.number}}">20</option>
<option value="?paginate_by=50&{{page_obj.number}}">50</option>
</select>
Passez l' paginate_by
objet dans le html et ajoutez-le aux liens de pagination. voir ci-dessous le code:
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?paginate_by={{ paginate_by}}&page=1">First</a>
<a class="btn btn-outline-info mb-4" href="?paginate_by={{ paginate_by}}&page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="?paginate_by={{ paginate_by}}&page={{ num }}">{{num}}</a>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a class="btn btn-outline-info mb-4" href="?paginate_by={{ paginate_by}}&page={{ num }}">{{num}}</a>
{% endif %}
{% endfor %}
{%if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?paginate_by={{ paginate_by}}&page={{page_obj.next_page_number}}">Next</a>
<a class="btn btn-outline-info mb-4" href="?paginate_by={{ paginate_by}}&page={{ page_obj.paginator.num_pages }}">Last</a>
{% endif %}
{% endif %}