from apps.utils.serializers import CustomModelSerializer from rest_framework import serializers from .models import Paper class PaperListSerializer(CustomModelSerializer): abstract = serializers.SerializerMethodField() pdf_url = serializers.SerializerMethodField() xml_url = serializers.SerializerMethodField() class Meta: model = Paper fields = '__all__' def get_abstract(self, obj) -> str: # PaperAbstract 是 O2O,related_name="abstract";无行 / has_abstract=False 时返空串 abs_obj = getattr(obj, "abstract", None) if abs_obj is None: return "" return abs_obj.abstract or "" def _media_url(self, obj, ext: str) -> str: """拼 /media/papers////. 静态直链。 date 缺失(unknown 目录)/ doi 缺失返空串 —— LLM 拿到空串就知道没法直链下, 改走 get_paper / paper_pdf_view。 """ if obj.publication_date is None or not obj.doi: return "" safe_doi = obj.doi.replace("/", "_") d = obj.publication_date path = f"/media/papers/{d.year}/{d.month}/{d.day}/{safe_doi}.{ext}" request = self.context.get("request") return request.build_absolute_uri(path) if request else path def get_pdf_url(self, obj) -> str: return self._media_url(obj, "pdf") if obj.has_fulltext_pdf else "" def get_xml_url(self, obj) -> str: return self._media_url(obj, "xml") if obj.has_fulltext_xml else ""