J'ai cette vue:

class PageView(ListView):
    # ... code ...
    paginate_by = 4

Dans le modèle, j'ai quelque chose comme:

<div class="pagination">
          <span class="page-links">
              {% if page_obj.has_previous %}
                  <a href="{{ request.path }}?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="{{ request.path }}?page={{ page_obj.next_page_number }}">next</a>
              {% endif %}
          </span>
        </div>

Comment puis-je transformer la variable GET ?page=number pour qu'elle ressemble à /page/number/ dans django?

2
yierstem 21 avril 2017 à 17:00

3 réponses

Meilleure réponse

Je ne peux pas le tester maintenant, mais vous devriez pouvoir réutiliser tout ListView.

Jetez un œil à django.views.generic.list.MultipleObjectMixin#paginate_queryset:

def paginate_queryset(self, queryset, page_size):
    """
    Paginate the queryset, if needed.
    """
    paginator = self.get_paginator(
        queryset, page_size, orphans=self.get_paginate_orphans(),
        allow_empty_first_page=self.get_allow_empty())
    page_kwarg = self.page_kwarg

    # HERE
    page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1

    try:
        page_number = int(page)
    except ValueError:
        if page == 'last':
            page_number = paginator.num_pages
        else:
            raise Http404(_("Page is not 'last', nor can it be converted to an int."))
    try:
        page = paginator.page(page_number)
        return (paginator, page, page.object_list, page.has_other_pages())
    except InvalidPage as e:
        raise Http404(_('Invalid page (%(page_number)s): %(message)s') % {
            'page_number': page_number,
            'message': str(e)
        })

Cela signifie que Django cherche d'abord le numéro de page dans la vue kwargs, puis dans les paramètres get.

Les valeurs de self.kwargs proviennent de la vue **kwargs - voir django.views.generic.base.View#as_view. Cela signifie que vous devriez être capable de définir simplement une URL comme url(r'^event/(?P<page>'d+)/$' et de l'utiliser avec votre CBV existant - il devrait récupérer le numéro de page tout seul.

1
Kos 21 avril 2017 à 14:22

D'ACCORD. Je l'ai résolu. En fait, quand j'avais:

url(r'^events/(?P<page>[0-9]+)/$', views.PageView.as_view(), name='events'),

Cela génère une erreur car l'argument page est manquant et urls.py ne connaît pas le chemin /events/.

Donc, dans mon mappage d'url (urls.py), j'ai écrit:

url(r'^events/$', views.PageView.as_view(), name='events'),
url(r'^events/(?P<page>[a-z0-9]+)/$', views.PageView.as_view(), name='events'),

Quand je vais à /events/, aucun argument n'est nécessaire, page est réglé sur 1 car aucun page_kwarg n'est fourni, tout va bien.

Quand je vais à /events/<page>/, prend cette variable et finalement ça marche.

Edit: j'ai mis [a-z0-9] au lieu de [0-9] car c'est nécessaire lorsque vous accédez à /events/last/. Dans la balise de modèle d'url, je dois fournir last sous forme de chaîne: {% url 'events' 'last' %}

Merci pour les réponses, si vous pensez que ma solution n'est pas bonne, veuillez commenter ci-dessous ma réponse.

Désolé pour ma grammaire.

0
yierstem 21 avril 2017 à 16:39

Par exemple, vous pouvez utiliser la fonction d'affichage:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def listOfSomethinView(request, page):
    paginator(Something.objects.all(), 10)
    try:
        list_of_something = paginator.page(page)
    except PageNotAnInteger:
        list_of_something = paginator.page(1)
    except EmptyPage:
        list_of_something = paginator.page(paginator.num_pages)

    return render(request, 'path_to_your_template', {
        'list_of_something': list_of_something,
    })

Dans urls.py ajoutez ceci:

url(r'^event/(?P<page>[0-9]{1,10})/$', views.listOfSomethingView, name='listOfSomething')

Dans votre modèle, utilisez quelque chose comme ça

{% url 'app:listOfSomething' paginator.previous_page_number %}
0
devalone 21 avril 2017 à 14:12