diff --git a/gallery/admin.py b/gallery/admin.py index 5e9ca83..f3d77f8 100644 --- a/gallery/admin.py +++ b/gallery/admin.py @@ -11,7 +11,7 @@ from imagekit.processors import ResizeToFit from gallery.models import Album, City, Location, Photo, Redir -# Thumbnail-luokka admin-näkymää varten +# Thumbnail spec for admin previews class AdminThumbnailSpec(ImageSpec): processors = [ResizeToFit(100, 100)] format = 'JPEG' @@ -19,7 +19,7 @@ class AdminThumbnailSpec(ImageSpec): def cached_admin_thumb(instance): - """Palauttaa cachetetun thumbnailin, jos kuva on olemassa.""" + """Return cached thumbnail for admin display if photo exists.""" if instance.photo: cached = ImageCacheFile(AdminThumbnailSpec(instance.photo)) cached.generate() @@ -27,7 +27,6 @@ def cached_admin_thumb(instance): return None -# 🔹 RedirAdmin – uudelleenohjausten hallinta class RedirAdmin(admin.ModelAdmin): list_display = ('path', 'album', 'test_url') search_fields = ('path',) @@ -36,21 +35,18 @@ class RedirAdmin(admin.ModelAdmin): list_editable = ('album',) def formfield_for_foreignkey(self, db_field, request, **kwargs): - """Järjestää albumivalikon aakkosjärjestykseen.""" if db_field.name == "album": kwargs["queryset"] = Album.objects.all().order_by('name') return super().formfield_for_foreignkey(db_field, request, **kwargs) def test_url(self, obj): - """Luo linkin, jolla voi testata uudelleenohjauksen.""" + """Generate clickable test link for redirection.""" return format_html( - 'http://nyymix.net/{}', - obj.path, obj.path + 'http://nyymix.net/{0}', obj.path ) test_url.short_description = "Test Redirection" -# 🔹 CityAdmin – kaupunkien hallinta class CityAdmin(admin.ModelAdmin): list_display = ('name',) search_fields = ('name',) @@ -58,16 +54,13 @@ class CityAdmin(admin.ModelAdmin): list_per_page = 30 -# 🔹 LocationAdmin – sijaintien hallinta class LocationAdmin(admin.ModelAdmin): list_display = ('city', 'place') list_filter = ('city',) ordering = ('city__name',) - search_fields = ('place', 'city__name',) + search_fields = ('place', 'city__name') list_per_page = 30 - -# 🔹 AlbumAdmin – albumien hallinta class AlbumAdmin(admin.ModelAdmin): prepopulated_fields = {'slug': ('name',)} list_display = ('name', 'location', 'album_date', 'is_public', 'upload_link', 'thumbnail') @@ -79,7 +72,7 @@ class AlbumAdmin(admin.ModelAdmin): change_form_template = "admin/gallery/album/change_form.html" def get_urls(self): - """Lisää mukautetun URL-reitin valokuvien lataamiselle.""" + """Add custom upload route to admin.""" urls = super().get_urls() custom_urls = [ path('/upload/', self.admin_site.admin_view(self.upload_photos), name="gallery_album_upload"), @@ -87,9 +80,8 @@ class AlbumAdmin(admin.ModelAdmin): return custom_urls + urls def upload_photos(self, request, album_id, *args, **kwargs): - """Käsittelee valokuvien lataamisen albumiin.""" + """Handle photo upload via admin UI.""" album = get_object_or_404(Album, id=album_id) - if request.method == 'POST' and request.FILES: uploaded_files = request.FILES.getlist('photo') if not uploaded_files: @@ -102,7 +94,7 @@ class AlbumAdmin(admin.ModelAdmin): return render(request, 'admin/upload_photos.html', {'album': album}) def upload_link(self, obj): - """Lisää 'Upload Photos' -painikkeen albumin muokkaussivulle.""" + """Show 'Upload Photos' button in album list.""" if obj.id: url = reverse("admin:gallery_album_upload", kwargs={"album_id": obj.id}) return format_html('Upload Photos', url) @@ -110,7 +102,7 @@ class AlbumAdmin(admin.ModelAdmin): upload_link.short_description = "Upload Photos" def thumbnail(self, obj): - """Näyttää albumin kansikuvan pikkukuvan.""" + """Show album cover thumbnail.""" if obj.cover and obj.cover.photo: return format_html( '', @@ -120,7 +112,7 @@ class AlbumAdmin(admin.ModelAdmin): thumbnail.short_description = "Thumbnail" def cover_preview(self, obj): - """Näyttää albumin kansikuvan suurempana esikatseluna.""" + """Preview full-size cover image in album admin page.""" if obj.cover and obj.cover.photo: return format_html( '', @@ -130,22 +122,13 @@ class AlbumAdmin(admin.ModelAdmin): cover_preview.short_description = "Cover Preview" def formfield_for_foreignkey(self, db_field, request, **kwargs): - """ - Suodattaa 'cover'-valinnan niin, että se näyttää vain albumiin kuuluvat kuvat. - Uuden albumin luonnissa vaihtoehto pidetään tyhjänä. - """ + """Limit cover image choices to photos in this album.""" if db_field.name == "cover": - # Jos albumia ollaan luomassa (ei pk:ta), ei anneta mitään vaihtoehtoja - if request.resolver_match.kwargs.get("object_id") is None: - kwargs["queryset"] = Photo.objects.none() - else: - # Haetaan vain nykyiseen albumiin kuuluvat kuvat - album_id = request.resolver_match.kwargs.get("object_id") - kwargs["queryset"] = Photo.objects.filter(album_id=album_id) + album_id = request.resolver_match.kwargs.get("object_id") + kwargs["queryset"] = Photo.objects.filter(album_id=album_id) if album_id else Photo.objects.none() return super().formfield_for_foreignkey(db_field, request, **kwargs) -# 🔹 PhotoAdmin – kuvien hallinta class PhotoAdmin(admin.ModelAdmin): list_display = ('slug', 'album', 'is_favorite', 'admin_thumbnail') list_display_links = ('slug',) @@ -157,9 +140,9 @@ class PhotoAdmin(admin.ModelAdmin): list_editable = ('is_favorite',) -# 🔹 Rekisteröidään admin-paneeliin +# Register models in admin admin.site.register(City, CityAdmin) admin.site.register(Location, LocationAdmin) admin.site.register(Album, AlbumAdmin) admin.site.register(Photo, PhotoAdmin) -admin.site.register(Redir, RedirAdmin) +admin.site.register(Redir, RedirAdmin) \ No newline at end of file diff --git a/gallery/templates/gallery/album_detail.html b/gallery/templates/gallery/album_detail.html index 4c22bd5..ac1a69c 100644 --- a/gallery/templates/gallery/album_detail.html +++ b/gallery/templates/gallery/album_detail.html @@ -3,7 +3,7 @@ -{% block title %} Gallery : Albums : {{ album.name }} {% endblock %} +{% block title %} Gallery : {{ album.name }} {% endblock %} {% block parallax %} diff --git a/gallery/templates/gallery/photo_detail.html b/gallery/templates/gallery/photo_detail.html index 52a4b4e..ccab3d0 100644 --- a/gallery/templates/gallery/photo_detail.html +++ b/gallery/templates/gallery/photo_detail.html @@ -2,7 +2,7 @@ {% load exif_filters %} -{% block title %} Gallery : Photo : {{ photo.slug }} {% endblock %} +{% block title %} Gallery : {{ photo.album.name }} : {{ photo.slug }} {% endblock %} @@ -71,7 +71,7 @@
{{ photo.likes }}
-
Download
+
Download photo
{{ photo.width }}x{{ photo.height }}
@@ -104,7 +104,7 @@
{{ photo.exif.FocalLength|exif_focallength}}
-
Focal Length
+
Focal Length in 35mm
{{ photo.exif.FocalLengthIn35mmFilm|exif_focallength }}
diff --git a/gallery/templates/gallery/search.html b/gallery/templates/gallery/search.html index 878e6a7..cc68d1d 100644 --- a/gallery/templates/gallery/search.html +++ b/gallery/templates/gallery/search.html @@ -13,21 +13,25 @@ {% block content %}
- {% for album in results %} -
-
-
- - {{ album.name }} - -
-
-

{{ album }}

-

{{ album.album_date|date:"d.m.Y" }} • {{ album.photos_in_album }} photos

+ {% if results %} + {% for album in results %} +
+
+
+ + {{ album.name }} + +
+
+

{{ album }}

+

{{ album.album_date|date:"d.m.Y" }} • {{ album.photos_in_album }} photos

+
-
- {% endfor %} + {% endfor %} + {% else %} +

Not found: "{{ query }}".

+ {% endif %}
{% include "./partials/pagination.html" %} diff --git a/gallery/views.py b/gallery/views.py index 35329a7..5fa8bb7 100644 --- a/gallery/views.py +++ b/gallery/views.py @@ -8,14 +8,15 @@ from .models import Album, Photo, Redir class AlbumsList(ListView): + """Displays a paginated list of public albums.""" model = Album template_name = 'gallery/album_list.html' - queryset = Album.objects.filter(is_public=True) - ordering = ['-album_date'] + queryset = Album.objects.filter(is_public=True).order_by('-album_date') paginate_by = 30 class AlbumDetail(DetailView): + """Shows a single album and its paginated photos.""" model = Album template_name = 'gallery/album_detail.html' @@ -26,33 +27,39 @@ class AlbumDetail(DetailView): context = super().get_context_data(**kwargs) photos = self.object.photos.all().order_by('taken_at') - # Pagination paginator = Paginator(photos, 30) - page_number = self.request.GET.get('page') - page_obj = paginator.get_page(page_number) + page_obj = paginator.get_page(self.request.GET.get('page')) - # Return - context['photos'] = page_obj.object_list - context['page_obj'] = page_obj + context.update({ + 'photos': page_obj.object_list, + 'page_obj': page_obj + }) return context + class PhotosList(ListView): + """Shows all public photos sorted by user-selected ordering.""" model = Photo paginate_by = 30 def get_queryset(self): - orderdic = {'latest': '-taken_at', 'liked': 'likes', 'popular': '-views'} - order = orderdic.get(self.request.GET.get('order', 'latest'), '-taken_at') + ordering_options = { + 'latest': '-taken_at', + 'liked': 'likes', + 'popular': '-views' + } + 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, *args, **kwargs): - context = super().get_context_data(*args, **kwargs) + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) context['order'] = self.request.GET.get('order', 'latest') 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' @@ -62,43 +69,48 @@ class PhotoDetail(DetailView): photo_slug = self.kwargs.get('photo_slug') photo = get_object_or_404(Photo, 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, *args, **kwargs): - context = super().get_context_data(*args, **kwargs) - context["next"] = self.object.get_next() - context["prev"] = self.object.get_prev() + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context.update({ + "next": self.object.get_next(), + "prev": self.object.get_prev() + }) return context def post(self, request, *args, **kwargs): photo = self.get_object() - if request.POST.get("like") == "true": - if self.request.session.get(photo.slug) == 0: - photo.add_like() - self.request.session[photo.slug] = 1 + if request.POST.get("like") == "true" and self.request.session.get(photo.slug) == 0: + photo.add_like() + self.request.session[photo.slug] = 1 - if request.user.is_authenticated: - photo.is_favorite = True - photo.save() + if request.user.is_authenticated: + photo.is_favorite = True + photo.save() return redirect('gallery:photo_url', album_slug=self.kwargs['album_slug'], photo_slug=self.kwargs['photo_slug']) class About(TemplateView): + """Static about page.""" template_name = "gallery/about.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context["about"] = settings.ABOUT_PAGE_SETTINGS # Haetaan asetukset + context["about"] = settings.ABOUT_PAGE_SETTINGS return context + class Search(TemplateView): + """Search view for public albums by name, place or city.""" template_name = "gallery/search.html" def get_context_data(self, **kwargs): @@ -115,17 +127,19 @@ class Search(TemplateView): Q(location__city__name__icontains=query) ).order_by('-album_date').distinct() - paginator = Paginator(results, 30) - page_number = self.request.GET.get('page') - page_obj = paginator.get_page(page_number) + paginator = Paginator(results, 30) + page_obj = paginator.get_page(self.request.GET.get('page')) - context['results'] = page_obj.object_list - context['page_obj'] = page_obj - context['paginator'] = paginator - context['is_paginated'] = page_obj.has_other_pages() + context.update({ + 'results': page_obj.object_list, + 'page_obj': page_obj, + 'paginator': paginator, + 'is_paginated': page_obj.has_other_pages() + }) 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) - diff --git a/templates/base.html b/templates/base.html deleted file mode 100644 index bdee05b..0000000 --- a/templates/base.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - {% load static %} - - - - - - - - - - - {% block title %} Gallery {% endblock %} - - - - - - {% block parallax %} - {% endblock %} - - - {% block navbar %} -
- -
- - -
-
- - -
-
- {% endblock %} - - -
- - {% block breadcrumb %} {% endblock %} -
- - -
- {% block content %} No Content {% endblock %} -
- - -
- © {% now "Y" %} Nyymix, powered by muistox. -
- - - - - - - \ No newline at end of file