Super basic Pagination

This commit is contained in:
MatthiasSaihttam 2021-10-12 09:30:25 -04:00
parent 07284eb087
commit 81ee2b368f
4 changed files with 115 additions and 2 deletions

89
main/pagination.py Normal file
View File

@ -0,0 +1,89 @@
import datetime
from django.utils.text import slugify
from .models import Thought
class Page:
def __init__(self, formatted_name):
self.formatted_name = formatted_name
self.slug = slugify(formatted_name)
def get_all_entries(self):
pass
class SeasonPage(Page):
def __init__(self, current_season, current_year):
super().__init__(["Winter", "Spring", "Summer", "Fall"][current_season] + " " + str(current_year))
self.first_day_of_season = datetime.date(
current_year,
12 if current_season == 0 else current_season * 3,
1
)
# If the current season is winter, then the next season starts on the next year
# This is actually the first day of the next season but that's hard to type out and it's 2am
self.last_day_of_season = datetime.date(
current_year + (1 if current_season == 0 else 0),
12 if current_season == 3 else (current_season + 1) * 3,
1
)
def get_all_entries(self):
return Thought.objects.order_by("-posted").filter(
posted__gte=self.first_day_of_season, # First month of this season
posted__lt=self.last_day_of_season # First month of next season
)
# Need to loop over all thoughts? and yield a new Page for each season
# Assume that if you're using this generator, you have at least 1 thought each
# season between the first and last
# We don't take into account timezone here. Because local time isn't monotonic increasing,
# it's ill-defined how to split up a list of items ordered by server time. This is annoying
# But the alternative is to call get_season for every thought and sort them into buckets
def season_pages():
ordered_thoughts = Thought.objects.order_by("posted")
first_thought = ordered_thoughts.first()
last_thought = ordered_thoughts.last()
# Okay we're going to use some wack seasons here hold on
# Let's go meteorological seasons
# 1 - jan -> 1, 0
# 2 - feb -> 2, 0
# 3 - mar -> 3, 1, spring
# 4 - apl -> 4, 1
# 5 - may -> 5, 1
# 6 - jun -> 6, 2, summer
# 7 - jul -> 7, 2
# 8 - aug -> 8, 2
# 9 - sep -> 9, 3, fall
# 10 - oct -> 10, 3
# 11 - nov -> 11, 3
# 12 - dec -> 0, 0, winter
def season_for_date(date):
return (date.month % 12) // 3
current_year = first_thought.posted.year
current_season = season_for_date(first_thought.posted)
while current_year < last_thought.posted.year or current_season != season_for_date(last_thought.posted):
yield SeasonPage(current_season, current_year)
if current_season == 0:
current_year += 1
current_season += 1
current_season = current_season % 4
yield SeasonPage(current_season, current_year)
def get_all_pages():
return list(season_pages())
# Where a Page has:
# .slug
# .formatted_name
# .get_all_entries
# return [Pages]

View File

@ -55,6 +55,14 @@
{% endfor %}
{% endblock %}
{% block footer %}
<nav id="page-nav">
{% for page in pages %}
<a href="?page={{ page.slug }}">{{ page.formatted_name }}</a>
{% endfor %}
</nav>
{% endblock %}
{% block scripts %}
<script>
const els = document.querySelectorAll(".thought");

View File

@ -31,6 +31,11 @@
{% endblock %}
</main>
<footer>
{% block footer %}
{% endblock %}
</footer>
{% block scripts %}
{% endblock %}

View File

@ -10,6 +10,7 @@ from django.utils.crypto import constant_time_compare
from whispermaphone import settings
from .models import Thought, ThoughtForm, ALLOWED_MEDIA_TYPES
from .pagination import get_all_pages
def check_authenticated(request):
authenticated = False
@ -29,12 +30,22 @@ def index(request):
except ValueError:
highlighted_uuid = ""
thoughts = Thought.objects.order_by("-posted")
pages = get_all_pages()
requested_page = pages[-1]
requested_slug = request.GET.get("page", default=requested_page.slug)
if requested_page.slug != requested_slug:
for p in pages:
if p.slug == requested_slug:
requested_page = p
thoughts = requested_page.get_all_entries()
return render(request, "whispermaphone/index.html", {
"thoughts": thoughts,
"highlighted": highlighted_uuid,
"authenticated": authenticated
"authenticated": authenticated,
"pages": pages
})