modifier la valeur de paginate_by pour toutes les pages

Nov 23 2020

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 ListViewclasse

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_byest 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

AmanGarg Nov 26 2020 at 00:42

En utilisant {{ request.GET.paginate_by }}, vous pouvez accéder aux paginate_byparamè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 %}

firstofis définira la valeur de paginate_bysur le paramètre de requête ou 5, qui sera la valeur par défaut.

ResleyRodrigues Dec 01 2020 at 14:00

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.

AjayLingayat Nov 25 2020 at 05:57

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_byobjet 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 %}