Update and optimize top tags
This commit is contained in:
parent
acb528b697
commit
7a419f3b14
1 changed files with 75 additions and 16 deletions
|
@ -1,3 +1,5 @@
|
|||
import random
|
||||
|
||||
from django import template
|
||||
from django.core.cache import cache
|
||||
from django.db.models import F
|
||||
|
@ -6,19 +8,21 @@ from gallery.models import Album, Photo
|
|||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def last_albums(count=5):
|
||||
# Returns the latest public albums, cached for 1 hour.
|
||||
cache_key = f"last_albums_{count}"
|
||||
albums = cache.get(cache_key)
|
||||
if albums is None:
|
||||
albums = Album.objects.filter(is_public=True).order_by("-album_date")[:count]
|
||||
cache.set(cache_key, albums, timeout=60 * 60) # 1h
|
||||
cache.set(cache_key, albums, timeout=60 * 60) # 1h
|
||||
return albums
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def top_photos(count=5):
|
||||
# Returns top photos by is_favorite, likes, and views.
|
||||
# Uses select_related to reduce DB hits. Cached for 1 hour.
|
||||
cache_key = f"top_photos_{count}"
|
||||
photos = cache.get(cache_key)
|
||||
if photos is None:
|
||||
|
@ -28,56 +32,112 @@ def top_photos(count=5):
|
|||
.order_by('-is_favorite', '-likes', '-views')
|
||||
.select_related('album')[:count]
|
||||
)
|
||||
cache.set(cache_key, albums, timeout=60 * 60) # 1h
|
||||
# FIXED: previously cached as 'albums' by mistake
|
||||
cache.set(cache_key, photos, timeout=60 * 60)
|
||||
return photos
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def random_photos_landscape(count=5):
|
||||
cache_key = f"random_photos_landscape_{count}"
|
||||
# Returns random landscape-oriented photos from public albums.
|
||||
# NO CACHING: always random.
|
||||
all_ids = list(
|
||||
Photo.objects
|
||||
.filter(album__is_public=True, width__gt=F('height'))
|
||||
.values_list('id', flat=True)[:500] # limit ID pool to improve performance
|
||||
)
|
||||
selected_ids = random.sample(all_ids, min(count, len(all_ids)))
|
||||
photos = Photo.objects.filter(id__in=selected_ids)
|
||||
return photos
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def random_favorite_photos_landscape(count=5):
|
||||
# Returns random landscape-oriented favorite photos from public albums.
|
||||
# If fewer than 'count' photos are available, returns an empty list.
|
||||
# Results are cached for 1 hour for performance.
|
||||
cache_key = f"random_favorite_photos_landscape_{count}"
|
||||
photos = cache.get(cache_key)
|
||||
if photos is None:
|
||||
photos = (
|
||||
Photo.objects
|
||||
.filter(album__is_public=True, width__gt=F('height'))
|
||||
.order_by('?')[:count]
|
||||
# Get all qualifying photos (landscape, favorite, public)
|
||||
queryset = Photo.objects.filter(
|
||||
is_favorite=True,
|
||||
width__gt=F('height'),
|
||||
album__is_public=True
|
||||
)
|
||||
cache.set(cache_key, photos, timeout=30) # 30 sec
|
||||
|
||||
if queryset.count() < count:
|
||||
return []
|
||||
|
||||
# Randomize and take the requested number
|
||||
photos = queryset.order_by('?')[:count]
|
||||
cache.set(cache_key, list(photos), timeout=60 * 60)
|
||||
|
||||
return photos
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def random_favorite_photos_portrait(count=5):
|
||||
# Returns random portrait-oriented favorite photos from public albums.
|
||||
# If fewer than 'count' photos are available, returns an empty list.
|
||||
# Results are cached for 1 hour for performance.
|
||||
cache_key = f"random_favorite_photos_portrait_{count}"
|
||||
photos = cache.get(cache_key)
|
||||
if photos is None:
|
||||
# Get all qualifying photos (portrait, favorite, public)
|
||||
queryset = Photo.objects.filter(
|
||||
is_favorite=True,
|
||||
height__gt=F('width'),
|
||||
album__is_public=True
|
||||
)
|
||||
|
||||
if queryset.count() < count:
|
||||
return []
|
||||
|
||||
photos = queryset.order_by('?')[:count]
|
||||
cache.set(cache_key, list(photos), timeout=60 * 60) # Cache as list, not queryset
|
||||
|
||||
return photos
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def top_photos_landscape(count=5):
|
||||
# Returns top landscape-oriented photos sorted by views.
|
||||
# Uses select_related and is cached for 1 hour.
|
||||
cache_key = f"top_photos_landscape_{count}"
|
||||
photos = cache.get(cache_key)
|
||||
if photos is None:
|
||||
if photos is None:
|
||||
photos = (
|
||||
Photo.objects
|
||||
.filter(album__is_public=True, width__gt=F('height'))
|
||||
.order_by('-views')
|
||||
.select_related('album')[:count]
|
||||
)
|
||||
cache.set(cache_key, photos, timeout=60 * 60) # 1h
|
||||
cache.set(cache_key, photos, timeout=60 * 60)
|
||||
return photos
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def top_photos_portrait(count=5):
|
||||
# Returns top portrait-oriented photos sorted by views.
|
||||
# Uses select_related and is cached for 1 hour.
|
||||
cache_key = f"top_photos_portrait_{count}"
|
||||
photos = cache.get(cache_key)
|
||||
if photos is None:
|
||||
if photos is None:
|
||||
photos = (
|
||||
Photo.objects
|
||||
.filter(album__is_public=True, height__gt=F('width'))
|
||||
.order_by('-views')
|
||||
.select_related('album')[:count]
|
||||
)
|
||||
cache.set(cache_key, photos, timeout=60 * 60) # 1h
|
||||
cache.set(cache_key, photos, timeout=60 * 60)
|
||||
return photos
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def top_photos_in_album(album, count=5):
|
||||
# Returns top photos in a specific album by favorite, likes, and views.
|
||||
# Cached for 1 hour using album.id as cache key part.
|
||||
cache_key = f"top_photos_album_{album.id}_{count}"
|
||||
photos = cache.get(cache_key)
|
||||
if photos is None:
|
||||
|
@ -87,6 +147,5 @@ def top_photos_in_album(album, count=5):
|
|||
.order_by('-is_favorite', '-likes', '-views')
|
||||
.select_related('album')[:count]
|
||||
)
|
||||
cache.set(cache_key, photos, timeout=60 * 60) # 1h
|
||||
return photos
|
||||
|
||||
cache.set(cache_key, photos, timeout=60 * 60)
|
||||
return photos
|
Loading…
Add table
Reference in a new issue