feat: paper list 返 abstract + 加 retrieve 端点 + filterset 扩 year range / 多字段
为 zcbot research skill 让出 LLM 友好接口:list 端点带 abstract 省 LLM 逐条 get 的 round-trip;PaperViewSet 加 CustomRetrieveModelMixin 修 GET /api/resm/paper/<id>/ 原本 404 的 bug;filterset_class 扩 publication_year_gte/lte + has_fulltext_pdf / is_oa / publication_name / first_author / openalex_id;queryset 加 select_related("abstract") 防 N+1。search_fields 不动(仍 title/first_author/first_author_institution)。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
326f6b35d5
commit
e8320bce05
|
|
@ -0,0 +1,26 @@
|
||||||
|
from django_filters import rest_framework as filters
|
||||||
|
from .models import Paper
|
||||||
|
|
||||||
|
|
||||||
|
class PaperFilterSet(filters.FilterSet):
|
||||||
|
# 年份范围(LLM 做"近 N 年文献"很常见)
|
||||||
|
publication_year_gte = filters.NumberFilter(field_name="publication_year", lookup_expr="gte")
|
||||||
|
publication_year_lte = filters.NumberFilter(field_name="publication_year", lookup_expr="lte")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Paper
|
||||||
|
fields = [
|
||||||
|
# 原有
|
||||||
|
"publication_year",
|
||||||
|
"type",
|
||||||
|
"fetch_status",
|
||||||
|
"has_abstract",
|
||||||
|
"has_fulltext",
|
||||||
|
"doi",
|
||||||
|
# 新增
|
||||||
|
"has_fulltext_pdf", # 比 has_fulltext 更准:zcbot research skill 的 has_pdf 参数走这个
|
||||||
|
"is_oa", # 是否开放获取
|
||||||
|
"publication_name", # 期刊精确名
|
||||||
|
"first_author", # 作者精确名
|
||||||
|
"openalex_id", # OpenAlex 唯一标识(等价 doi)
|
||||||
|
]
|
||||||
|
|
@ -1,7 +1,18 @@
|
||||||
from apps.utils.serializers import CustomModelSerializer
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
|
from rest_framework import serializers
|
||||||
from .models import Paper
|
from .models import Paper
|
||||||
|
|
||||||
|
|
||||||
class PaperListSerializer(CustomModelSerializer):
|
class PaperListSerializer(CustomModelSerializer):
|
||||||
|
abstract = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Paper
|
model = Paper
|
||||||
fields = '__all__'
|
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 ""
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ from rest_framework.decorators import api_view, permission_classes
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
from .models import Paper, PaperAbstract
|
from .models import Paper, PaperAbstract
|
||||||
from .serializers import PaperListSerializer
|
from .serializers import PaperListSerializer
|
||||||
|
from .filters import PaperFilterSet
|
||||||
from apps.utils.viewsets import CustomGenericViewSet, CustomListModelMixin
|
from apps.utils.viewsets import CustomGenericViewSet, CustomListModelMixin
|
||||||
|
from apps.utils.mixins import CustomRetrieveModelMixin
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -31,11 +33,10 @@ paper_pdf_view.cls.swagger_schema = None
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class PaperViewSet(CustomGenericViewSet, CustomListModelMixin):
|
class PaperViewSet(CustomGenericViewSet, CustomListModelMixin, CustomRetrieveModelMixin):
|
||||||
queryset = Paper.objects.all()
|
queryset = Paper.objects.select_related("abstract").all()
|
||||||
serializer_class = PaperListSerializer
|
serializer_class = PaperListSerializer
|
||||||
filterset_fields = ["publication_year", "type", "fetch_status",
|
filterset_class = PaperFilterSet
|
||||||
"has_abstract", "has_fulltext", "doi"]
|
|
||||||
search_fields = ['title', 'first_author', 'first_author_institution']
|
search_fields = ['title', 'first_author', 'first_author_institution']
|
||||||
ordering = ["-publication_date", "-create_time"]
|
ordering = ["-publication_date", "-create_time"]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue