From f943e1fdaff04b9af1349fa4c9c53290f77a7943 Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Sat, 26 Sep 2020 15:13:55 +0200 Subject: [PATCH] Implement pagination for news archive For now we do 10 items per page, but that's easy to adjust. Paginate based on the date (so create an index on the date field to simplify this), making page rendering and load a *lot* faster. --- pgweb/news/migrations/0007_news_date_idx.py | 19 +++++++++++++++++++ pgweb/news/models.py | 2 +- pgweb/news/views.py | 21 ++++++++++++++++++--- pgweb/urls.py | 2 +- templates/news/newsarchive.html | 12 ++++++++++-- 5 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 pgweb/news/migrations/0007_news_date_idx.py diff --git a/pgweb/news/migrations/0007_news_date_idx.py b/pgweb/news/migrations/0007_news_date_idx.py new file mode 100644 index 00000000..53fc6517 --- /dev/null +++ b/pgweb/news/migrations/0007_news_date_idx.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.11 on 2020-09-26 13:11 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('news', '0006_sending_email'), + ] + + operations = [ + migrations.AlterField( + model_name='newsarticle', + name='date', + field=models.DateField(db_index=True, default=datetime.date.today), + ), + ] diff --git a/pgweb/news/models.py b/pgweb/news/models.py index d4920ef5..3b2948d9 100644 --- a/pgweb/news/models.py +++ b/pgweb/news/models.py @@ -27,7 +27,7 @@ class NewsTag(models.Model): class NewsArticle(TwoModeratorsMixin, TristateModerateModel): org = models.ForeignKey(Organisation, null=False, blank=False, verbose_name="Organisation", help_text="If no organisations are listed, please check the organisation list and contact the organisation manager or webmaster@postgresql.org if none are listed.", on_delete=models.CASCADE) email = models.ForeignKey(OrganisationEmail, null=True, blank=True, verbose_name="Reply email", help_text="Pick a confirmed email associated with the organisation. This will be used as the reply address of posted news.", on_delete=models.CASCADE) - date = models.DateField(null=False, blank=False, default=date.today) + date = models.DateField(null=False, blank=False, default=date.today, db_index=True) title = models.CharField(max_length=200, null=False, blank=False) content = models.TextField(null=False, blank=False) tweeted = models.BooleanField(null=False, blank=False, default=False) diff --git a/pgweb/news/views.py b/pgweb/news/views.py index d06a8779..b09cadb1 100644 --- a/pgweb/news/views.py +++ b/pgweb/news/views.py @@ -7,18 +7,33 @@ from pgweb.util.moderation import ModerationState from .models import NewsArticle, NewsTag +import datetime import json +# Number of items per page in the news archive +NEWS_ITEMS_PER_PAGE = 10 -def archive(request, tag=None, paging=None): - if tag: + +def archive(request, tag=None, paginator=None): + if tag and tag.strip('/'): tag = get_object_or_404(NewsTag, urlname=tag.strip('/')) news = NewsArticle.objects.select_related('org').filter(modstate=ModerationState.APPROVED, tags=tag) else: tag = None news = NewsArticle.objects.select_related('org').filter(modstate=ModerationState.APPROVED) + if paginator and paginator.strip('/'): + news = news.filter(date__lte=datetime.datetime.strptime(paginator.strip('/'), '%Y%m%d')) + + allnews = list(news.order_by('-date')[:NEWS_ITEMS_PER_PAGE + 1]) + if len(allnews) == NEWS_ITEMS_PER_PAGE + 1: + # 11 means we have a second page, so set a paginator link + paginator = allnews[9].date.strftime("%Y%m%d") + else: + paginator = None + return render_pgweb(request, 'about', 'news/newsarchive.html', { - 'news': news, + 'news': allnews[:NEWS_ITEMS_PER_PAGE], + 'paginator': paginator, 'tag': tag, 'newstags': NewsTag.objects.all(), }) diff --git a/pgweb/urls.py b/pgweb/urls.py index 2c5d754c..a65dc231 100644 --- a/pgweb/urls.py +++ b/pgweb/urls.py @@ -33,7 +33,7 @@ urlpatterns = [ url(r'^dyncss/(?Pbase).css$', pgweb.core.views.dynamic_css), url(r'^about/$', pgweb.core.views.about), - url(r'^about/newsarchive/([^/]+/)?$', pgweb.news.views.archive), + url(r'^about/newsarchive/(?P[^/]*/)?(?P[0-9]{8}/)?$', pgweb.news.views.archive), url(r'^about/news/(?P\d+)(?P-.*)?/$', pgweb.news.views.item), url(r'^about/news/(?P[^/]+)-(?P\d+)/$', pgweb.news.views.item), url(r'^about/news/taglist.json/$', pgweb.news.views.taglist_json), diff --git a/templates/news/newsarchive.html b/templates/news/newsarchive.html index 2324e3ab..d38c7301 100644 --- a/templates/news/newsarchive.html +++ b/templates/news/newsarchive.html @@ -2,7 +2,7 @@ {%load markup%} {%block title%}News Archive{%if tag%} - {{tag.name}}{%endif%}{%endblock%} {%block contents%} -

News Archive{%if tag%} - {{tag.name}}{%endif%}

+

News Archive{%if tag%} - {{tag.name}}{%endif%}

{%for t in newstags%}{{t.name}} {%endfor%} @@ -14,5 +14,13 @@ {{obj.content|markdown:"safe"|striptags|truncatewords:20}}

Read more...

{%endfor%} -

Submit news

+ +{%if paginator%} +Older news... +{%endif%} + +

+ News articles are either from the PostgreSQL project or contributeed by other related organisations. If you with to share news + related to PostgreSQL, you may submit your own articles for consideration after logging in. +

{%endblock%} -- 2.39.5