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 import template
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
|
@ -6,19 +8,21 @@ from gallery.models import Album, Photo
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def last_albums(count=5):
|
def last_albums(count=5):
|
||||||
|
# Returns the latest public albums, cached for 1 hour.
|
||||||
cache_key = f"last_albums_{count}"
|
cache_key = f"last_albums_{count}"
|
||||||
albums = cache.get(cache_key)
|
albums = cache.get(cache_key)
|
||||||
if albums is None:
|
if albums is None:
|
||||||
albums = Album.objects.filter(is_public=True).order_by("-album_date")[:count]
|
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
|
return albums
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def top_photos(count=5):
|
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}"
|
cache_key = f"top_photos_{count}"
|
||||||
photos = cache.get(cache_key)
|
photos = cache.get(cache_key)
|
||||||
if photos is None:
|
if photos is None:
|
||||||
|
@ -28,26 +32,78 @@ def top_photos(count=5):
|
||||||
.order_by('-is_favorite', '-likes', '-views')
|
.order_by('-is_favorite', '-likes', '-views')
|
||||||
.select_related('album')[:count]
|
.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
|
return photos
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def random_photos_landscape(count=5):
|
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)
|
photos = cache.get(cache_key)
|
||||||
if photos is None:
|
if photos is None:
|
||||||
photos = (
|
# Get all qualifying photos (landscape, favorite, public)
|
||||||
Photo.objects
|
queryset = Photo.objects.filter(
|
||||||
.filter(album__is_public=True, width__gt=F('height'))
|
is_favorite=True,
|
||||||
.order_by('?')[:count]
|
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
|
return photos
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def top_photos_landscape(count=5):
|
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}"
|
cache_key = f"top_photos_landscape_{count}"
|
||||||
photos = cache.get(cache_key)
|
photos = cache.get(cache_key)
|
||||||
if photos is None:
|
if photos is None:
|
||||||
|
@ -57,12 +113,14 @@ def top_photos_landscape(count=5):
|
||||||
.order_by('-views')
|
.order_by('-views')
|
||||||
.select_related('album')[:count]
|
.select_related('album')[:count]
|
||||||
)
|
)
|
||||||
cache.set(cache_key, photos, timeout=60 * 60) # 1h
|
cache.set(cache_key, photos, timeout=60 * 60)
|
||||||
return photos
|
return photos
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def top_photos_portrait(count=5):
|
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}"
|
cache_key = f"top_photos_portrait_{count}"
|
||||||
photos = cache.get(cache_key)
|
photos = cache.get(cache_key)
|
||||||
if photos is None:
|
if photos is None:
|
||||||
|
@ -72,12 +130,14 @@ def top_photos_portrait(count=5):
|
||||||
.order_by('-views')
|
.order_by('-views')
|
||||||
.select_related('album')[:count]
|
.select_related('album')[:count]
|
||||||
)
|
)
|
||||||
cache.set(cache_key, photos, timeout=60 * 60) # 1h
|
cache.set(cache_key, photos, timeout=60 * 60)
|
||||||
return photos
|
return photos
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def top_photos_in_album(album, count=5):
|
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}"
|
cache_key = f"top_photos_album_{album.id}_{count}"
|
||||||
photos = cache.get(cache_key)
|
photos = cache.get(cache_key)
|
||||||
if photos is None:
|
if photos is None:
|
||||||
|
@ -87,6 +147,5 @@ def top_photos_in_album(album, count=5):
|
||||||
.order_by('-is_favorite', '-likes', '-views')
|
.order_by('-is_favorite', '-likes', '-views')
|
||||||
.select_related('album')[:count]
|
.select_related('album')[:count]
|
||||||
)
|
)
|
||||||
cache.set(cache_key, photos, timeout=60 * 60) # 1h
|
cache.set(cache_key, photos, timeout=60 * 60)
|
||||||
return photos
|
return photos
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue