muistox/gallery/views/album.py

129 lines
4 KiB
Python

from django.conf import settings
from django.core.cache import cache
from django.core.paginator import Paginator
from django.db.models import Count, F, Q, Sum
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.views import View
from django.views.generic import DetailView, ListView, TemplateView
from config.cache_durations import *
from gallery.cache import cached_or_set
from gallery.utils import build_canonical_url
from ..models import Album, Photo, Redir
class AlbumsList(ListView):
"""
Displays a paginated list of public albums.
Queryset is cached per page for ALBUM_LIST_PAGE_DURATION.
"""
model = Album
template_name = 'gallery/album_list.html'
paginate_by = 30
def get_queryset(self):
page = self.request.GET.get('page', 1)
key = f'album_list_queryset_page_{page}'
return cached_or_set(
key,
ALBUM_LIST_PAGE_DURATION,
lambda: (
Album.objects.filter(is_public=True)
.select_related('cover')
.annotate(
photo_count=Count('photos'),
total_views=Sum('photos__views')
)
.order_by('-album_date')
)
)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
page_obj = context.get('page_obj')
canonical_url = build_canonical_url(
self.request,
reverse('gallery:albums_url'),
params={'page': page_obj.number}
)
context.update({
'canonical_url': canonical_url,
})
return context
class AlbumDetail(DetailView):
"""Shows a single album and its paginated photos."""
model = Album
template_name = 'gallery/album_detail.html'
def get_object(self, queryset=None):
# return get_object_or_404(Album, slug=self.kwargs.get('album_slug'))
return get_object_or_404(Album, slug__iexact=self.kwargs.get('album_slug'))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# photos = self.object.photos.all().order_by('taken_at')
photos = self.object.photos.all().select_related('album').order_by('taken_at')
paginator = Paginator(photos, 30)
page_obj = paginator.get_page(self.request.GET.get('page'))
# Canonical_url
canonical_url = build_canonical_url(
self.request,
self.object.get_absolute_url(),
params={'page': page_obj.number}
)
context.update({
'photos': page_obj.object_list,
'page_obj': page_obj,
'canonical_url': canonical_url,
})
return context
class AlbumSearch(TemplateView):
"""Search view for public albums by name, place or city."""
template_name = "gallery/album_search.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
query = self.request.GET.get('q', '').strip()
context['query'] = query
results = Album.objects.none()
if query:
results = Album.objects.filter(
Q(is_public=True),
Q(name__icontains=query) |
Q(location__place__icontains=query) |
Q(location__city__name__icontains=query)
).order_by('-album_date').distinct()
paginator = Paginator(results, 30)
page_obj = paginator.get_page(self.request.GET.get('page'))
# Canonical URL
canonical_url = build_canonical_url(
self.request,
reverse('gallery:search_url'),
params={'page': page_obj.number, 'q': query}
)
context.update({
'results': page_obj.object_list,
'page_obj': page_obj,
'paginator': paginator,
'is_paginated': page_obj.has_other_pages(),
'canonical_url': canonical_url
})
return context