muistox/gallery/views/album.py

122 lines
4.1 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, redirect
from django.urls import reverse
from django.views import View
from django.views.generic import DetailView, ListView, TemplateView
from ..models import Album, Photo, Redir
class AlbumsList(ListView):
"""Displays a paginated list of public albums."""
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}'
queryset = cache.get(key)
if not queryset:
queryset = (
Album.objects.filter(is_public=True)
.select_related('cover')
.annotate(
photo_count=Count('photos'),
total_views=Sum('photos__views')
)
.order_by('-album_date')
)
cache.set(key, queryset, 60 * 5)
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Canonical_url
page = self.request.GET.get('page')
if page and page != '1':
canonical_url = f"{self.request.build_absolute_uri(reverse('gallery:albums_url'))}?page={page}"
else:
canonical_url = self.request.build_absolute_uri(reverse('gallery:albums_url'))
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'))
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
page = self.request.GET.get('page')
if page and page != '1':
canonical_url = f"{self.request.build_absolute_uri(self.object.get_absolute_url())}?page={page}"
else:
canonical_url = self.request.build_absolute_uri(self.object.get_absolute_url())
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
page = self.request.GET.get('page')
base_url = self.request.build_absolute_uri(reverse('gallery:search_url'))
if page and page != '1':
canonical_url = f"{base_url}?page={page}"
else:
canonical_url = base_url
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