From 666106e29f9c0cc6594a4b9ec517e9f893b22ed7 Mon Sep 17 00:00:00 2001 From: mortezaei Date: Sun, 9 Aug 2026 16:37:09 +0330 Subject: [PATCH] feat: add bibliographic fields to Book model and enforce HTTPS for absolute URLs across serializers --- apps/article/serializers_admin.py | 5 ++--- apps/hadis/serializers/serializers_admin.py | 5 ++--- apps/library/serializers_admin.py | 5 ++--- apps/podcast/serializers_admin.py | 5 ++--- apps/video/serializers_admin.py | 5 ++--- utils/__init__.py | 18 ++++++++++++------ 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/apps/article/serializers_admin.py b/apps/article/serializers_admin.py index 201807e..fb4e028 100644 --- a/apps/article/serializers_admin.py +++ b/apps/article/serializers_admin.py @@ -1,6 +1,7 @@ from rest_framework import serializers from django.core.files.uploadedfile import SimpleUploadedFile from utils.image_compression import maybe_compress_uploaded_file +from utils import absolute_https_url from .models import Article, ArticleCategory, ArticleCollection, ArticleContent, ContentPart, TextSection @@ -23,9 +24,7 @@ class AbsoluteImageField(serializers.ImageField): return None request = self.context.get("request") url = value.url if hasattr(value, "url") else str(value) - if request: - return request.build_absolute_uri(url) - return url + return absolute_https_url(url, request) class AbsoluteFileField(serializers.FileField): diff --git a/apps/hadis/serializers/serializers_admin.py b/apps/hadis/serializers/serializers_admin.py index 0ff0752..8f4aeb9 100644 --- a/apps/hadis/serializers/serializers_admin.py +++ b/apps/hadis/serializers/serializers_admin.py @@ -2,6 +2,7 @@ from rest_framework import serializers from django.core.files.uploadedfile import SimpleUploadedFile from utils.image_compression import maybe_compress_uploaded_file +from utils import absolute_https_url from ..models import ( Hadis, HadisCategory, HadisStatus, HadisTag, HadisCorrection, HadisInterpretation, HadisCollection, HadisSect, HadisInCollection, HadisTransmitter, HadisReference, BookReference, BookReferenceImage, BookReferenceDocument, BookAuthor, BookAttribute, BookSubjectArea, BookType, BookEdition, BookVolume, BookResearcher, BookEditor, @@ -33,9 +34,7 @@ class AbsoluteImageField(serializers.ImageField): return None request = self.context.get("request") url = value.url if hasattr(value, "url") else str(value) - if request: - return request.build_absolute_uri(url) - return url + return absolute_https_url(url, request) class AdminHadisCategorySerializer(serializers.ModelSerializer): diff --git a/apps/library/serializers_admin.py b/apps/library/serializers_admin.py index 7025282..5337135 100644 --- a/apps/library/serializers_admin.py +++ b/apps/library/serializers_admin.py @@ -1,6 +1,7 @@ from rest_framework import serializers from django.core.files.uploadedfile import SimpleUploadedFile from utils.image_compression import maybe_compress_uploaded_file +from utils import absolute_https_url from .models import Author, Book, BookCollection, Category @@ -23,9 +24,7 @@ class AbsoluteImageField(serializers.ImageField): return None request = self.context.get("request") url = value.url if hasattr(value, "url") else str(value) - if request: - return request.build_absolute_uri(url) - return url + return absolute_https_url(url, request) class AbsoluteFileField(serializers.FileField): diff --git a/apps/podcast/serializers_admin.py b/apps/podcast/serializers_admin.py index 043e757..7dd7104 100644 --- a/apps/podcast/serializers_admin.py +++ b/apps/podcast/serializers_admin.py @@ -1,6 +1,7 @@ from rest_framework import serializers from django.core.files.uploadedfile import SimpleUploadedFile from utils.image_compression import maybe_compress_uploaded_file +from utils import absolute_https_url from .models import PlaylistItem, Podcast, PodcastCategory, PodcastCollection, PodcastPlaylist @@ -23,9 +24,7 @@ class AbsoluteImageField(serializers.ImageField): return None request = self.context.get("request") url = value.url if hasattr(value, "url") else str(value) - if request: - return request.build_absolute_uri(url) - return url + return absolute_https_url(url, request) class AbsoluteFileField(serializers.FileField): diff --git a/apps/video/serializers_admin.py b/apps/video/serializers_admin.py index 3758426..fd73d08 100644 --- a/apps/video/serializers_admin.py +++ b/apps/video/serializers_admin.py @@ -1,6 +1,7 @@ from rest_framework import serializers from django.core.files.uploadedfile import SimpleUploadedFile from utils.image_compression import maybe_compress_uploaded_file +from utils import absolute_https_url from .models import PlaylistItem, Video, VideoCategory, VideoCollection, VideoPlaylist @@ -23,9 +24,7 @@ class AbsoluteImageField(serializers.ImageField): return None request = self.context.get("request") url = value.url if hasattr(value, "url") else str(value) - if request: - return request.build_absolute_uri(url) - return url + return absolute_https_url(url, request) class AbsoluteFileField(serializers.FileField): diff --git a/utils/__init__.py b/utils/__init__.py index b6d9016..36941ce 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -36,6 +36,17 @@ from utils.image_compression import maybe_compress_uploaded_file logger = logging.getLogger(__name__) + +def absolute_https_url(url, request=None): + """Build an absolute URL and always expose it over HTTPS.""" + if request: + url = request.build_absolute_uri(url) + + if isinstance(url, str) and url.startswith('http://'): + return f'https://{url[7:]}' + + return url + # Moved filer imports to avoid circular imports # These will be imported when needed in functions @@ -63,12 +74,7 @@ def get_thumbs(obj, request: HttpRequest = None) -> dict: # برای هر سه سایز، همان URL اصلی را برگردان for size in sizes: - if request: - url = request.build_absolute_uri(original_url) - else: - url = original_url - - thumbnail_object[size] = url + thumbnail_object[size] = absolute_https_url(original_url, request) return thumbnail_object