From 538b480c6a92ef57b621d379de0b1ebc683c3cde Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Thu, 22 Oct 2026 10:26:55 +0330 Subject: [PATCH] refactor(links): format of link enhancemed and fixed on endpoints with links format issue --- apps/hadis/models/hadis.py | 2 +- apps/hadis/serializers/hadis.py | 64 ++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/apps/hadis/models/hadis.py b/apps/hadis/models/hadis.py index b8fcc75..376383c 100644 --- a/apps/hadis/models/hadis.py +++ b/apps/hadis/models/hadis.py @@ -598,7 +598,7 @@ class HadisInterpretation(models.Model): cat_slug = self.category.slug if (self.category_id and self.category) else self.slug if cat_slug: #https://dovodi.newhorizonco.uk/arguments/hadith/excellence-of-character-56?tab=explanation - return f"{settings.DOVODI_DOMAIN}/arguments/hadith/{self.slug}?tab=explanation"i + return f"{settings.DOVODI_DOMAIN}/arguments/hadith/{self.slug}?tab=explanation" return None class Meta: diff --git a/apps/hadis/serializers/hadis.py b/apps/hadis/serializers/hadis.py index 9278c10..9307734 100644 --- a/apps/hadis/serializers/hadis.py +++ b/apps/hadis/serializers/hadis.py @@ -658,40 +658,72 @@ def format_address_output(ref_or_data): def format_links_output(links_data): + """ + Standardizes links into a list of structured objects: + [ + {"title": "Dorar", "url": "https://dorar.net/hadith/3420"}, + {"title": "IslamWeb", "url": "https://www.islamweb.net/ar/fatwa/1909"} + ] + Handles dict, list of dicts, list of strings, and raw JSON strings cleanly. + """ if not links_data: return [] + + # 1. Parse JSON string if stored as string if isinstance(links_data, str): trimmed = links_data.strip() - if trimmed.startswith("[") or trimmed.startswith("{"): + if trimmed.startswith(("[", "{")): try: import json parsed = json.loads(trimmed) return format_links_output(parsed) - except (ValueError, TypeError): + except (ValueError, TypeError, json.JSONDecodeError): pass - return [trimmed] if trimmed else [] - elif isinstance(links_data, dict): + return [{"title": "Link", "url": trimmed}] if trimmed else [] + + # 2. Main case: Dict format from React Admin {"Title": "URL"} + if isinstance(links_data, dict): out = [] - for k, v in links_data.items(): - if isinstance(v, str) and v.strip(): - out.append(v.strip()) - elif isinstance(v, (list, dict)): - out.extend(format_links_output(v)) + for title, url_or_obj in links_data.items(): + if isinstance(url_or_obj, str) and url_or_obj.strip(): + out.append({ + "title": str(title).strip(), + "url": url_or_obj.strip() + }) + elif isinstance(url_or_obj, dict): + # Nested dict safety: e.g. {"Dorar": {"url": "...", "title": "..."}} + url = url_or_obj.get("url") or url_or_obj.get("link") or url_or_obj.get("href") + t = url_or_obj.get("title") or title + if url and isinstance(url, str) and url.strip(): + out.append({ + "title": str(t).strip(), + "url": url.strip() + }) + elif isinstance(url_or_obj, list): + out.extend(format_links_output(url_or_obj)) return out - elif isinstance(links_data, list): + + # 3. List case: e.g. [{"title": "...", "url": "..."}, "https://..."] + if isinstance(links_data, list): out = [] for item in links_data: - if isinstance(item, str): - s = item.strip() - if s: - out.append(s) + if isinstance(item, str) and item.strip(): + out.append({ + "title": "Link", + "url": item.strip() + }) elif isinstance(item, dict): - url = item.get('url') or item.get('link') or item.get('href') or item.get('value') + url = item.get("url") or item.get("link") or item.get("href") or item.get("value") + title = item.get("title") or item.get("name") or "Link" if url and isinstance(url, str) and url.strip(): - out.append(url.strip()) + out.append({ + "title": str(title).strip(), + "url": url.strip() + }) elif isinstance(item, list): out.extend(format_links_output(item)) return out + return []