mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-01-23 02:35:14 +00:00
Optimize VOD streams retrieval by using prefetch_related to eliminate N+1 queries
This commit is contained in:
parent
e7201b4429
commit
ac5df3fd28
1 changed files with 48 additions and 36 deletions
|
|
@ -1045,7 +1045,8 @@ def xc_get_vod_categories(user):
|
|||
|
||||
def xc_get_vod_streams(request, user, category_id=None):
|
||||
"""Get VOD streams (movies) for XtreamCodes API"""
|
||||
from apps.vod.models import Movie
|
||||
from apps.vod.models import Movie, M3UMovieRelation
|
||||
from django.db.models import Prefetch
|
||||
|
||||
streams = []
|
||||
|
||||
|
|
@ -1068,44 +1069,55 @@ def xc_get_vod_streams(request, user, category_id=None):
|
|||
if category_id:
|
||||
filters["m3u_relations__category_id"] = category_id
|
||||
|
||||
# Get movies directly with their relations
|
||||
movies = Movie.objects.filter(**filters).select_related('logo').distinct()
|
||||
# Optimize with prefetch_related to eliminate N+1 queries
|
||||
# This loads all relations in a single query instead of one per movie
|
||||
movies = Movie.objects.filter(**filters).select_related('logo').prefetch_related(
|
||||
Prefetch(
|
||||
'm3u_relations',
|
||||
queryset=M3UMovieRelation.objects.filter(
|
||||
m3u_account__is_active=True
|
||||
).select_related('m3u_account', 'category').order_by('-m3u_account__priority', 'id'),
|
||||
to_attr='active_relations'
|
||||
)
|
||||
).distinct()
|
||||
|
||||
for movie in movies:
|
||||
# Get the highest priority relation for this movie (for metadata like container_extension)
|
||||
relation = movie.m3u_relations.filter(
|
||||
m3u_account__is_active=True
|
||||
).select_related('m3u_account').order_by('-m3u_account__priority', 'id').first()
|
||||
# Get the first (highest priority) relation from prefetched data
|
||||
# This avoids the N+1 query problem entirely
|
||||
if hasattr(movie, 'active_relations') and movie.active_relations:
|
||||
relation = movie.active_relations[0]
|
||||
else:
|
||||
# Fallback - should rarely be needed with proper prefetching
|
||||
continue
|
||||
|
||||
if relation:
|
||||
relation_custom = relation.custom_properties or {}
|
||||
relation_info = relation_custom.get('basic_data', {})
|
||||
streams.append({
|
||||
"num": movie.id,
|
||||
"name": movie.name,
|
||||
"stream_type": "movie",
|
||||
"stream_id": movie.id,
|
||||
"stream_icon": (
|
||||
None if not movie.logo
|
||||
else build_absolute_uri_with_port(
|
||||
request,
|
||||
reverse("api:channels:logo-cache", args=[movie.logo.id])
|
||||
)
|
||||
),
|
||||
#'stream_icon': movie.logo.url if movie.logo else '',
|
||||
"rating": movie.rating or "0",
|
||||
"rating_5based": round(float(movie.rating or 0) / 2, 2) if movie.rating else 0,
|
||||
"added": str(movie.created_at.timestamp()),
|
||||
"is_adult": 0,
|
||||
"tmdb_id": movie.tmdb_id or "",
|
||||
"imdb_id": movie.imdb_id or "",
|
||||
"trailer": (movie.custom_properties or {}).get('youtube_trailer') or relation_info.get('youtube_trailer') or relation_info.get('trailer', ''),
|
||||
"category_id": str(relation.category.id) if relation.category else "0",
|
||||
"category_ids": [int(relation.category.id)] if relation.category else [],
|
||||
"container_extension": relation.container_extension or "mp4",
|
||||
"custom_sid": None,
|
||||
"direct_source": "",
|
||||
})
|
||||
relation_custom = relation.custom_properties or {}
|
||||
relation_info = relation_custom.get('basic_data', {})
|
||||
streams.append({
|
||||
"num": movie.id,
|
||||
"name": movie.name,
|
||||
"stream_type": "movie",
|
||||
"stream_id": movie.id,
|
||||
"stream_icon": (
|
||||
None if not movie.logo
|
||||
else build_absolute_uri_with_port(
|
||||
request,
|
||||
reverse("api:channels:logo-cache", args=[movie.logo.id])
|
||||
)
|
||||
),
|
||||
#'stream_icon': movie.logo.url if movie.logo else '',
|
||||
"rating": movie.rating or "0",
|
||||
"rating_5based": round(float(movie.rating or 0) / 2, 2) if movie.rating else 0,
|
||||
"added": str(movie.created_at.timestamp()),
|
||||
"is_adult": 0,
|
||||
"tmdb_id": movie.tmdb_id or "",
|
||||
"imdb_id": movie.imdb_id or "",
|
||||
"trailer": (movie.custom_properties or {}).get('youtube_trailer') or relation_info.get('youtube_trailer') or relation_info.get('trailer', ''),
|
||||
"category_id": str(relation.category.id) if relation.category else "0",
|
||||
"category_ids": [int(relation.category.id)] if relation.category else [],
|
||||
"container_extension": relation.container_extension or "mp4",
|
||||
"custom_sid": None,
|
||||
"direct_source": "",
|
||||
})
|
||||
|
||||
return streams
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue