Split views & remove converters
This commit is contained in:
parent
a3264db994
commit
52dc390781
7 changed files with 281 additions and 266 deletions
|
@ -1,10 +0,0 @@
|
||||||
class FilenamePathConverter:
|
|
||||||
regex = '[a-zA-Z0-9_-]{1,50}\.[a-zA-Z]{3,4}$'
|
|
||||||
|
|
||||||
def to_python(self, value):
|
|
||||||
# convert value to its corresponding python datatype
|
|
||||||
return value
|
|
||||||
|
|
||||||
def to_url(self, value):
|
|
||||||
# convert the value to str data
|
|
||||||
return value
|
|
|
@ -1,13 +1,13 @@
|
||||||
from django.urls import path, re_path, register_converter
|
from django.urls import path, re_path
|
||||||
|
|
||||||
from . import converters, views
|
from . import views
|
||||||
|
|
||||||
app_name = 'gallery'
|
app_name = 'gallery'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.Main.as_view(), name='main_url'),
|
path('', views.Main.as_view(), name='main_url'),
|
||||||
path('about/', views.About.as_view(), name='about_url'),
|
path('about/', views.About.as_view(), name='about_url'),
|
||||||
path('search/', views.Search.as_view(), name='search_url'),
|
path('search/', views.AlbumSearch.as_view(), name='search_url'),
|
||||||
path('photostream/', views.PhotosList.as_view(), name='photos_url'),
|
path('photostream/', views.PhotosList.as_view(), name='photos_url'),
|
||||||
re_path(r'^like/(?P<album_slug>.+)/(?P<photo_slug>[a-zA-Z0-9_-]{1,50}\.[a-zA-Z]{3,4})/?$', views.PhotoLike.as_view(), name='photo_like_url'),
|
re_path(r'^like/(?P<album_slug>.+)/(?P<photo_slug>[a-zA-Z0-9_-]{1,50}\.[a-zA-Z]{3,4})/?$', views.PhotoLike.as_view(), name='photo_like_url'),
|
||||||
re_path(r'^slideshow/(?P<album_slug>.+)/(?P<photo_slug>[a-zA-Z0-9_-]{1,50}\.[a-zA-Z]{3,4})/?$', views.PhotoSlideshow.as_view(), name='photo_slideshow_url'),
|
re_path(r'^slideshow/(?P<album_slug>.+)/(?P<photo_slug>[a-zA-Z0-9_-]{1,50}\.[a-zA-Z]{3,4})/?$', views.PhotoSlideshow.as_view(), name='photo_slideshow_url'),
|
||||||
|
|
253
gallery/views.py
253
gallery/views.py
|
@ -1,253 +0,0 @@
|
||||||
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 Main(TemplateView):
|
|
||||||
"""Main homepage."""
|
|
||||||
template_name = "gallery/main.html"
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
context['canonical_url'] = self.request.build_absolute_uri(reverse('gallery:main_url'))
|
|
||||||
context['latest_albums'] = Album.objects.filter(is_public=True).order_by('-album_date')[:6]
|
|
||||||
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
page = int(self.request.GET.get('page', 1))
|
|
||||||
|
|
||||||
# Canonical_url
|
|
||||||
canonical_url = self.request.build_absolute_uri(reverse('gallery:albums_url'))
|
|
||||||
if page > 1:
|
|
||||||
canonical_url += f'?page={page}'
|
|
||||||
context['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 = int(self.request.GET.get('page', 1))
|
|
||||||
canonical_url = self.request.build_absolute_uri(self.object.get_absolute_url())
|
|
||||||
if page > 1:
|
|
||||||
canonical_url += f'?page={page}'
|
|
||||||
|
|
||||||
context.update({
|
|
||||||
'photos': page_obj.object_list,
|
|
||||||
'page_obj': page_obj,
|
|
||||||
'canonical_url': canonical_url,
|
|
||||||
})
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
class PhotosList(ListView):
|
|
||||||
"""Shows all public photos sorted by user-selected ordering."""
|
|
||||||
model = Photo
|
|
||||||
paginate_by = 30
|
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
ordering_options = {
|
|
||||||
'latest': '-taken_at',
|
|
||||||
'liked': '-likes',
|
|
||||||
'popular': '-views',
|
|
||||||
'favorite': '-is_favorite'
|
|
||||||
}
|
|
||||||
order = ordering_options.get(self.request.GET.get('order', 'latest'), '-taken_at')
|
|
||||||
return Photo.objects.filter(album__is_public=True).order_by(order).select_related('album')
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
context['order'] = self.request.GET.get('order', 'latest')
|
|
||||||
context['canonical_url'] = self.request.build_absolute_uri(reverse('gallery:photos_url'))
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
class PhotoDetail(DetailView):
|
|
||||||
"""Shows a single photo and handles liking functionality."""
|
|
||||||
model = Photo
|
|
||||||
slug_url_kwarg = 'photo_slug'
|
|
||||||
template_name = 'gallery/photo_detail.html'
|
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
|
||||||
album_slug = self.kwargs.get('album_slug')
|
|
||||||
photo_slug = self.kwargs.get('photo_slug')
|
|
||||||
# photo = get_object_or_404(Photo, slug=photo_slug, album__slug=album_slug)
|
|
||||||
photo = get_object_or_404(Photo.objects.select_related('album'), slug=photo_slug, album__slug=album_slug)
|
|
||||||
|
|
||||||
# Track views using session to avoid duplicate counts
|
|
||||||
if photo.slug not in self.request.session:
|
|
||||||
photo.add_view()
|
|
||||||
self.request.session[photo.slug] = 0
|
|
||||||
|
|
||||||
return photo
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
context.update({
|
|
||||||
"next": self.object.get_next(),
|
|
||||||
"prev": self.object.get_prev(),
|
|
||||||
"canonical_url": self.request.build_absolute_uri(self.object.get_absolute_url()),
|
|
||||||
"liked": self.request.session.get(f"liked_{self.object.slug}", False)
|
|
||||||
})
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
class PhotoLike(View):
|
|
||||||
"""Ajax like photo button."""
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
return JsonResponse({'error': 'This endpoint only supports POST requests.'}, status=405)
|
|
||||||
|
|
||||||
def post(self, request, album_slug, photo_slug):
|
|
||||||
photo = get_object_or_404(Photo.objects.select_related('album'), slug=photo_slug, album__slug=album_slug)
|
|
||||||
session_key = f"liked_{photo.slug}"
|
|
||||||
liked = request.session.get(session_key, False)
|
|
||||||
|
|
||||||
if not liked:
|
|
||||||
photo.likes += 1
|
|
||||||
if request.user.is_authenticated:
|
|
||||||
photo.is_favorite = True
|
|
||||||
request.session[session_key] = True
|
|
||||||
status = "liked"
|
|
||||||
else:
|
|
||||||
photo.likes = max(0, photo.likes - 1)
|
|
||||||
if request.user.is_authenticated:
|
|
||||||
photo.is_favorite = False
|
|
||||||
request.session[session_key] = False
|
|
||||||
status = "unliked"
|
|
||||||
|
|
||||||
photo.save()
|
|
||||||
return JsonResponse({'success': True, 'likes': photo.likes, 'status': status})
|
|
||||||
|
|
||||||
|
|
||||||
class PhotoSlideshow(DetailView):
|
|
||||||
model = Photo
|
|
||||||
slug_url_kwarg = 'photo_slug'
|
|
||||||
template_name = 'gallery/photo_slideshow.html'
|
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
|
||||||
album_slug = self.kwargs.get('album_slug')
|
|
||||||
photo_slug = self.kwargs.get('photo_slug')
|
|
||||||
photo = get_object_or_404(
|
|
||||||
Photo.objects.select_related('album'),
|
|
||||||
slug=photo_slug,
|
|
||||||
album__slug=album_slug
|
|
||||||
)
|
|
||||||
|
|
||||||
if photo.slug not in self.request.session:
|
|
||||||
photo.add_view()
|
|
||||||
self.request.session[photo.slug] = 0
|
|
||||||
|
|
||||||
return photo
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
current_photo = self.object
|
|
||||||
|
|
||||||
next_photo = current_photo.get_next()
|
|
||||||
|
|
||||||
if not next_photo:
|
|
||||||
next_photo = Photo.objects.filter(album=current_photo.album).order_by('taken_at').first()
|
|
||||||
|
|
||||||
context.update({
|
|
||||||
"next_photo": next_photo,
|
|
||||||
"liked": self.request.session.get(f"liked_{current_photo.slug}", False)
|
|
||||||
})
|
|
||||||
return context
|
|
||||||
|
|
||||||
class Search(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'))
|
|
||||||
|
|
||||||
context.update({
|
|
||||||
'results': page_obj.object_list,
|
|
||||||
'page_obj': page_obj,
|
|
||||||
'paginator': paginator,
|
|
||||||
'is_paginated': page_obj.has_other_pages(),
|
|
||||||
'canonical_url': self.request.build_absolute_uri(reverse('gallery:search_url'))
|
|
||||||
})
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
class About(TemplateView):
|
|
||||||
"""Static about page."""
|
|
||||||
template_name = "gallery/about.html"
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
context['canonical_url'] = self.request.build_absolute_uri(reverse('gallery:about_url'))
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
def redirect_to_album(request, redir_path):
|
|
||||||
"""Handles redirect logic for shortened/legacy album URLs."""
|
|
||||||
redir = get_object_or_404(Redir, path=redir_path)
|
|
||||||
return redirect('gallery:album_url', album_slug=redir.album.slug)
|
|
3
gallery/views/__init__.py
Normal file
3
gallery/views/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from .album import *
|
||||||
|
from .main import *
|
||||||
|
from .photo import *
|
110
gallery/views/album.py
Normal file
110
gallery/views/album.py
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
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)
|
||||||
|
page = int(self.request.GET.get('page', 1))
|
||||||
|
|
||||||
|
# Canonical_url
|
||||||
|
canonical_url = self.request.build_absolute_uri(reverse('gallery:albums_url'))
|
||||||
|
if page > 1:
|
||||||
|
canonical_url += f'?page={page}'
|
||||||
|
context['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 = int(self.request.GET.get('page', 1))
|
||||||
|
canonical_url = self.request.build_absolute_uri(self.object.get_absolute_url())
|
||||||
|
if page > 1:
|
||||||
|
canonical_url += f'?page={page}'
|
||||||
|
|
||||||
|
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'))
|
||||||
|
|
||||||
|
context.update({
|
||||||
|
'results': page_obj.object_list,
|
||||||
|
'page_obj': page_obj,
|
||||||
|
'paginator': paginator,
|
||||||
|
'is_paginated': page_obj.has_other_pages(),
|
||||||
|
'canonical_url': self.request.build_absolute_uri(reverse('gallery:search_url'))
|
||||||
|
})
|
||||||
|
return context
|
39
gallery/views/main.py
Normal file
39
gallery/views/main.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
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 Main(TemplateView):
|
||||||
|
"""Main homepage."""
|
||||||
|
template_name = "gallery/main.html"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['canonical_url'] = self.request.build_absolute_uri(reverse('gallery:main_url'))
|
||||||
|
context['latest_albums'] = Album.objects.filter(is_public=True).order_by('-album_date')[:6]
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class About(TemplateView):
|
||||||
|
"""Static about page."""
|
||||||
|
template_name = "gallery/about.html"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['canonical_url'] = self.request.build_absolute_uri(reverse('gallery:about_url'))
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
def redirect_to_album(request, redir_path):
|
||||||
|
"""Handles redirect logic for shortened/legacy album URLs."""
|
||||||
|
redir = get_object_or_404(Redir, path=redir_path)
|
||||||
|
return redirect('gallery:album_url', album_slug=redir.album.slug)
|
126
gallery/views/photo.py
Normal file
126
gallery/views/photo.py
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
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 PhotosList(ListView):
|
||||||
|
"""Shows all public photos sorted by user-selected ordering."""
|
||||||
|
model = Photo
|
||||||
|
paginate_by = 30
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
ordering_options = {
|
||||||
|
'latest': '-taken_at',
|
||||||
|
'liked': 'likes',
|
||||||
|
'popular': '-views',
|
||||||
|
'favorite': '-is_favorite'
|
||||||
|
}
|
||||||
|
order = ordering_options.get(self.request.GET.get('order', 'latest'), '-taken_at')
|
||||||
|
return Photo.objects.filter(album__is_public=True).order_by(order).select_related('album')
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['order'] = self.request.GET.get('order', 'latest')
|
||||||
|
context['canonical_url'] = self.request.build_absolute_uri(reverse('gallery:photos_url'))
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class PhotoDetail(DetailView):
|
||||||
|
"""Shows a single photo and handles liking functionality."""
|
||||||
|
model = Photo
|
||||||
|
slug_url_kwarg = 'photo_slug'
|
||||||
|
template_name = 'gallery/photo_detail.html'
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
album_slug = self.kwargs.get('album_slug')
|
||||||
|
photo_slug = self.kwargs.get('photo_slug')
|
||||||
|
photo = get_object_or_404(Photo.objects.select_related('album'), slug=photo_slug, album__slug=album_slug)
|
||||||
|
|
||||||
|
if photo.slug not in self.request.session:
|
||||||
|
photo.add_view()
|
||||||
|
self.request.session[photo.slug] = 0
|
||||||
|
|
||||||
|
return photo
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context.update({
|
||||||
|
"next": self.object.get_next(),
|
||||||
|
"prev": self.object.get_prev(),
|
||||||
|
"canonical_url": self.request.build_absolute_uri(self.object.get_absolute_url()),
|
||||||
|
"liked": self.request.session.get(f"liked_{self.object.slug}", False)
|
||||||
|
})
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class PhotoLike(View):
|
||||||
|
"""Ajax like photo button."""
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
return JsonResponse({'error': 'This endpoint only supports POST requests.'}, status=405)
|
||||||
|
|
||||||
|
def post(self, request, album_slug, photo_slug):
|
||||||
|
photo = get_object_or_404(Photo.objects.select_related('album'), slug=photo_slug, album__slug=album_slug)
|
||||||
|
session_key = f"liked_{photo.slug}"
|
||||||
|
liked = request.session.get(session_key, False)
|
||||||
|
|
||||||
|
if not liked:
|
||||||
|
photo.likes += 1
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
photo.is_favorite = True
|
||||||
|
request.session[session_key] = True
|
||||||
|
status = "liked"
|
||||||
|
else:
|
||||||
|
photo.likes = max(0, photo.likes - 1)
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
photo.is_favorite = False
|
||||||
|
request.session[session_key] = False
|
||||||
|
status = "unliked"
|
||||||
|
|
||||||
|
photo.save()
|
||||||
|
return JsonResponse({'success': True, 'likes': photo.likes, 'status': status})
|
||||||
|
|
||||||
|
|
||||||
|
class PhotoSlideshow(DetailView):
|
||||||
|
"""Slideshow."""
|
||||||
|
model = Photo
|
||||||
|
slug_url_kwarg = 'photo_slug'
|
||||||
|
template_name = 'gallery/photo_slideshow.html'
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
album_slug = self.kwargs.get('album_slug')
|
||||||
|
photo_slug = self.kwargs.get('photo_slug')
|
||||||
|
photo = get_object_or_404(
|
||||||
|
Photo.objects.select_related('album'),
|
||||||
|
slug=photo_slug,
|
||||||
|
album__slug=album_slug
|
||||||
|
)
|
||||||
|
|
||||||
|
if photo.slug not in self.request.session:
|
||||||
|
photo.add_view()
|
||||||
|
self.request.session[photo.slug] = 0
|
||||||
|
|
||||||
|
return photo
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
current_photo = self.object
|
||||||
|
|
||||||
|
next_photo = current_photo.get_next()
|
||||||
|
|
||||||
|
if not next_photo:
|
||||||
|
next_photo = Photo.objects.filter(album=current_photo.album).order_by('taken_at').first()
|
||||||
|
|
||||||
|
context.update({
|
||||||
|
"next_photo": next_photo,
|
||||||
|
"liked": self.request.session.get(f"liked_{current_photo.slug}", False)
|
||||||
|
})
|
||||||
|
return context
|
Loading…
Add table
Reference in a new issue