diff --git a/gallery/templates/gallery/photo_detail.html b/gallery/templates/gallery/photo_detail.html
index c15bca2..95ca9f8 100644
--- a/gallery/templates/gallery/photo_detail.html
+++ b/gallery/templates/gallery/photo_detail.html
@@ -81,19 +81,16 @@
Likes
-
{{ photo.likes }}
+
{{ photo.likes }}
-
@@ -137,11 +134,46 @@
-
-
-
-
-
+
+
+
+ {% if liked %}
+
+ {% endif %}
+
{% endblock %}
\ No newline at end of file
diff --git a/gallery/urls.py b/gallery/urls.py
index 042625e..6731ecc 100644
--- a/gallery/urls.py
+++ b/gallery/urls.py
@@ -13,6 +13,7 @@ urlpatterns = [
path('about/', views.About.as_view(), name='about_url'),
path('search/', views.Search.as_view(), name='search_url'),
path('photostream/', views.PhotosList.as_view(), name='photos_url'),
+ path('like//', views.PhotoLike.as_view(), name='photo_like_url'),
path('albums//', views.PhotoDetail.as_view(), name='photo_url'),
path('albums//', views.AlbumDetail.as_view(), name='album_url'),
path('albums/', views.AlbumsList.as_view(), name='albums_url'),
diff --git a/gallery/views.py b/gallery/views.py
index 4782b13..a815e8b 100644
--- a/gallery/views.py
+++ b/gallery/views.py
@@ -2,8 +2,10 @@ from django.conf import settings
from django.core.cache import cache
from django.core.paginator import Paginator
from django.db.models import Count, Q, Sum
-from django.shortcuts import get_object_or_404, redirect, render
+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
@@ -33,7 +35,7 @@ class AlbumsList(ListView):
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))
@@ -43,7 +45,7 @@ class AlbumsList(ListView):
if page > 1:
canonical_url += f'?page={page}'
context['canonical_url'] = canonical_url
-
+
return context
@@ -57,7 +59,7 @@ class AlbumDetail(DetailView):
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().order_by('taken_at')
photos = self.object.photos.all().select_related('album').order_by('taken_at')
paginator = Paginator(photos, 30)
@@ -77,7 +79,6 @@ class AlbumDetail(DetailView):
return context
-
class PhotosList(ListView):
"""Shows all public photos sorted by user-selected ordering."""
model = Photo
@@ -108,7 +109,7 @@ class PhotoDetail(DetailView):
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, 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
@@ -124,21 +125,37 @@ class PhotoDetail(DetailView):
"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
- def post(self, request, *args, **kwargs):
- photo = self.get_object()
- if request.POST.get("like") == "true" and self.request.session.get(photo.slug) == 0:
- photo.add_like()
- self.request.session[photo.slug] = 1
+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
- photo.save()
+ 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"
- return redirect('gallery:photo_url', album_slug=self.kwargs['album_slug'], photo_slug=self.kwargs['photo_slug'])
+ photo.save()
+ return JsonResponse({'success': True, 'likes': photo.likes, 'status': status})
class Search(TemplateView):
@@ -175,6 +192,7 @@ class Search(TemplateView):
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'))