Hello, I started working on this bug. I have a working patch but it requires still some work. I am not sure how to do the js part so for the moment i concentrated on the non js requirements.
I have a question though: I have enabled only the unstable repository and I don't have many news to test what i ve done. Is there any other solution to test/work this besides adding more repositories? I attach the initial patch although there still work to be done (avoid copy pasting pagination code, add some tests, redirection from the old PTS) Cheers, Orestis
From 9ee2c25655e7f2a8a82f20be35635095000430ad Mon Sep 17 00:00:00 2001 From: Orestis Ioannou <ores...@oioannou.com> Date: Wed, 2 Sep 2015 10:38:10 +0200 Subject: [PATCH] Add pagination for the package news --- distro_tracker/core/panels.py | 15 +++++++- .../core/templates/core/package_news.html | 43 ++++++++++++++++++++++ .../core/templates/core/panels/news.html | 13 ++++++- distro_tracker/core/views.py | 31 ++++++++++++++++ distro_tracker/project/urls.py | 4 ++ 5 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 distro_tracker/core/templates/core/package_news.html diff --git a/distro_tracker/core/panels.py b/distro_tracker/core/panels.py index 8c2cd82..fd1144e 100644 --- a/distro_tracker/core/panels.py +++ b/distro_tracker/core/panels.py @@ -12,6 +12,7 @@ from __future__ import unicode_literals from django.conf import settings from django.utils.functional import cached_property from django.core.exceptions import ObjectDoesNotExist +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.utils import six from django.utils.safestring import mark_safe from distro_tracker.core.utils.plugins import PluginRegistry @@ -804,8 +805,18 @@ class NewsPanel(BasePanel): @cached_property def context(self): news = News.objects.prefetch_related('signed_by') - news = news.filter(package=self.package).order_by('-datetime_created') - news = news[:self.NEWS_LIMIT] + package_news = (news.filter(package=self.package) + .order_by('-datetime_created')) + paginator = Paginator(package_news, self.NEWS_LIMIT) + page = self.request.GET.get('page') or 1 + try: + news = paginator.page(page) + except PageNotAnInteger: + # If page is not an integer, deliver first page. + news = paginator.page(1) + except EmptyPage: + # If page is out of range (e.g. 9999), deliver last page of results. + news = paginator.page(paginator.num_pages) return { 'news': news } diff --git a/distro_tracker/core/templates/core/package_news.html b/distro_tracker/core/templates/core/package_news.html new file mode 100644 index 0000000..132bcb0 --- /dev/null +++ b/distro_tracker/core/templates/core/package_news.html @@ -0,0 +1,43 @@ +{% extends 'core/base.html' %} + +{% block content %} +<h1 class="text-center">News for package <a href="{% url 'dtracker-package-page' package %}">{{ package }}</a></h1> +<div class="row-fluid"> +<ul class="list-group list-group-flush"> + {% for news_item in news %} + <li class="list-group-item"> + [<span class="news-date">{{ news_item.datetime_created|date:"Y-m-d" }}</span>] + <a href="{% url 'dtracker-news-page' news_item.pk %}"> + <span class="news-title">{{ news_item.title }}</span> + </a> + {% if news_item.created_by %}(<span class="news-creator">{{ news_item.created_by }}</span>){% endif %} + {% with signers=news_item.signed_by.all %} + {% if signers and signers.0.name != news_item.created_by %} + {% spaceless %} + <span>(signed by: </span> + {% for signer in signers %} + <span class="news-signer">{{ signer.name }}</span> + {% if not forloop.last %}<span>, </span>{% endif %} + {% endfor %} + <span>)</span> + {% endspaceless %} + {% endif %} + {% endwith %} + </li> + {% endfor %} +</ul> + +<div class="pagination"> + <span class="step-links"> + {% if news.has_previous %} + <a href="?page={{ news.previous_page_number }}">previous</a> + {% endif %} + <span class="current">Page {{ news.number }} of {{ news.paginator.num_pages }}.</span> + {% if news.has_next %} + <a href="?page={{ news.next_page_number }}">next</a> + {% endif %} + </span> +</div> + +</div> +{% endblock %} diff --git a/distro_tracker/core/templates/core/panels/news.html b/distro_tracker/core/templates/core/panels/news.html index 1cc38fd..5497cd9 100644 --- a/distro_tracker/core/templates/core/panels/news.html +++ b/distro_tracker/core/templates/core/panels/news.html @@ -3,7 +3,7 @@ {% block panel-header %} <div class="row-fluid"> <div class="pull-left"> - <span>{{ panel.title }}</span> + <span>{{ panel.title }} <a href="{% url 'dtracker-package-news' package.name %}"><i class='icon-share'></i></a></span> </div> <div class="pull-right"> <a title="rss feed" href="{% url 'dtracker-package-rss-news-feed' package.name %}"> @@ -37,4 +37,15 @@ </li> {% endfor %} </ul> +<div class="pagination"> + <span class="step-links"> + {% if panel.context.news.has_previous %} + <a href="?page={{ panel.contextnews.previous_page_number }}">previous</a> + {% endif %} + <span class="current">Page {{ panel.context.news.number }} of {{ panel.context.news.paginator.num_pages }}.</span> + {% if panel.context.news.has_next %} + <a href="?page={{ panel.context.news.next_page_number }}">next</a> + {% endif %} + </span> +</div> {% endblock %} diff --git a/distro_tracker/core/views.py b/distro_tracker/core/views.py index 16b958b..57ef74e 100644 --- a/distro_tracker/core/views.py +++ b/distro_tracker/core/views.py @@ -26,6 +26,7 @@ from django.views.decorators.cache import cache_control from django.core.mail import send_mail from django.core.exceptions import PermissionDenied from django.core.urlresolvers import reverse, reverse_lazy +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.utils.http import urlquote from distro_tracker.core.models import get_web_package from distro_tracker.core.forms import CreateTeamForm @@ -176,6 +177,36 @@ def news_page(request, news_id): }) +def package_news(request, package_name): + """ + A view that renders all the news of a package. Pagination included + """ + package = get_web_package(package_name) + if not package: + raise Http404 + _DEFAULT_NEWS_LIMIT = 30 + NEWS_LIMIT = getattr( + settings, + 'DISTRO_TRACKER_NEWS_PANEL_LIMIT', + _DEFAULT_NEWS_LIMIT) + news = News.objects.prefetch_related('signed_by') + news = news.filter(package=package).order_by('-datetime_created') + paginator = Paginator(news, NEWS_LIMIT) + page = request.GET.get('page') or 1 + try: + page_news = paginator.page(page) + except PageNotAnInteger: + # If page is not an integer, deliver first page. + page_news = paginator.page(1) + except EmptyPage: + # If page is out of range (e.g. 9999), deliver last page of results. + page_news = paginator.page(paginator.num_pages) + return render(request, 'core/package_news.html', { + 'package': package, + 'news': page_news, + }) + + class ActionItemJsonView(View): """ View renders a :class:`distro_tracker.core.models.ActionItem` in a JSON diff --git a/distro_tracker/project/urls.py b/distro_tracker/project/urls.py index cbe1fe8..f841858 100644 --- a/distro_tracker/project/urls.py +++ b/distro_tracker/project/urls.py @@ -213,6 +213,10 @@ urlpatterns = patterns( url(r'^teams/(?P<slug>.+?)/$', TeamDetailsView.as_view(), name='dtracker-team-page'), + # Package news page + url(r'^pkg/(?P<package_name>.+)/news/', + 'distro_tracker.core.views.package_news', + name='dtracker-package-news'), # Dedicated package page url(r'^pkg/(?P<package_name>[^/]+)/?$', -- 2.1.4
signature.asc
Description: OpenPGP digital signature