You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF JSON API使用HyperlinkedRelatedField时关联字段返回空对象问题

如何让Django REST Framework JSON API的报告资源返回包含关联交会事件的完整关系数据及链接

我正在开发空间交会报告的REST API,希望将交会事件(Conjunction)作为每个报告(Report)的子资源。目前使用ResourceRelatedField能正常返回关联数据,但换成HyperlinkedRelatedField时,relationships中的conjunctions返回空对象。我需要让输出同时包含关联数据ID和对应的关系链接,符合指定的JSON结构。

模型代码

from django.db import models
from django.utils import timezone

class Report(models.Model):
  class Meta:
    managed = False
    db_table = 'report'
    ordering = ['-id']

  predict_start = models.DateTimeField(null=True)
  predict_end = models.DateTimeField(null=True)
  process_duration = models.IntegerField(default=0, null=True)
  create_conjunction_date = models.DateTimeField(null=True)
  ephe_filename = models.CharField(max_length=100, null=True)

class Conjunction(models.Model):
  class Meta:
    managed = False
    db_table = 'conjunction'
    ordering = ['-conjunction_id']

  conjunction_id = models.IntegerField(primary_key=True)
  tca = models.DateTimeField(max_length=3, null=True)
  missdt = models.FloatField(null=True)
  probability = models.FloatField(null=True)
  prob_method = models.CharField(max_length=45, null=True)
  norad = models.OneToOneField(SatelliteCategory, to_field='norad_cat_id', db_column='norad', null=True, on_delete=models.DO_NOTHING)
  doy = models.FloatField(null=True)
  ephe_id = models.IntegerField(null=True)
  pri_obj = models.IntegerField(null=True)
  sec_obj = models.IntegerField(null=True)
  report = models.ForeignKey(Report, related_name='conjunctions', null=True, on_delete=models.DO_NOTHING)
  probability_foster = models.FloatField(null=True)
  probability_patera = models.FloatField(null=True)
  probability_alfano = models.FloatField(null=True)
  probability_chan = models.FloatField(null=True)

序列化器代码

class ConjunctionSerializer(serializers.ModelSerializer):
  class Meta:
    model = Conjunction
    fields = '__all__'

class ReportSerializer(serializers.ModelSerializer):
  conjunctions = relations.ResourceRelatedField(many=True, read_only=True)

  class Meta:
    model = Report
    fields = '__all__'

视图代码

from rest_framework import permissions
from rest_framework_json_api.views import viewsets
from .serializers import ReportSerializer, ConjunctionSerializer
from .models import Report, Conjunction

class ReportViewSet(viewsets.ModelViewSet):
  queryset = Report.objects.all()
  serializer_class = ReportSerializer
  permission_classes = [permissions.AllowAny]

class ConjunctionViewSet(viewsets.ModelViewSet):
  queryset = Conjunction.objects.all()
  serializer_class = ConjunctionSerializer
  permission_classes = [permissions.AllowAny]

路由配置

from django.contrib import admin
from django.urls import include, path
from rest_framework import routers
from api.views import UserViewSet, GroupViewSet
from shared.views import ReportViewSet, SatelliteCategoryViewSet, ConjunctionViewSet, ReportSentViewSet

router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'groups', GroupViewSet)
router.register(r'reports', ReportViewSet)
router.register(r'report_sent', ReportSentViewSet)
router.register(r'satellite_category', SatelliteCategoryViewSet)
router.register(r'conjunctions', ConjunctionViewSet)

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
  path('admin/', admin.site.urls),
  path('api/', include(router.urls)),
  path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

当前现象

使用ResourceRelatedField时的输出(正常返回关联数据)

{
    "links": {
        "first": "http://127.0.0.1:8000/api/reports/?page%5Bnumber%5D=1",
        "last": "http://127.0.0.1:8000/api/reports/?page%5Bnumber%5D=84",
        "next": "http://127.0.0.1:8000/api/reports/?page%5Bnumber%5D=2",
        "prev": null
    },
    "data": [
        {
            "type": "Report",
            "id": "838",
            "attributes": {
                "predict_start": "2023-01-26T12:00:00Z",
                "predict_end": "2023-02-02T12:00:00Z",
                "process_duration": 752,
                "create_conjunction_date": "2023-01-26T14:52:45Z",
                "ephe_filename": "Filename.txt"
            },
            "relationships": {
                "conjunctions": {
                    "meta": {
                        "count": 107
                    },
                    "data": [
                        {
                            "type": "Conjunction",
                            "id": "78728"
                        },
                        # ... more data ...
                        {
                            "type": "Conjunction",
                            "id": "78622"
                        }
                    ]
                }
            }
        }
    ],
    "meta": {
        "pagination": {
            "page": 1,
            "pages": 84,
            "count": 838
        }
    }
}

使用HyperlinkedRelatedField时的输出(关联数据为空)

{
    "links": {
        "first": "http://127.0.0.1:8000/api/reports/?page%5Bnumber%5D=1",
        "last": "http://127.0.0.1:8000/api/reports/?page%5Bnumber%5D=84",
        "next": "http://127.0.0.1:8000/api/reports/?page%5Bnumber%5D=2",
        "prev": null
    },
    "data": [
        {
            "type": "Report",
            "id": "838",
            "attributes": {
                "predict_start": "2023-01-26T12:00:00Z",
                "predict_end": "2023-02-02T12:00:00Z",
                "process_duration": 752,
                "create_conjunction_date": "2023-01-26T14:52:45Z",
                "ephe_filename": "Filename.txt"
            },
            "relationships": {
                "conjunctions": {}
            }
        },
    ],
    "meta": {
        "pagination": {
            "page": 1,
            "pages": 84,
            "count": 838
        }
    }
}

期望输出

{
    "links": {
        "first": "http://127.0.0.1:8000/api/reports/?page%5Bnumber%5D=1",
        "last": "http://127.0.0.1:8000/api/reports/?page%5Bnumber%5D=84",
        "next": "http://127.0.0.1:8000/api/reports/?page%5Bnumber%5D=2",
        "prev": null
    },
    "data": [
        {
            "type": "Report",
            "id": "838",
            "attributes": {
                "predict_start": "2023-01-26T12:00:00Z",
                "predict_end": "2023-02-02T12:00:00Z",
                "process_duration": 752,
                "create_conjunction_date": "2023-01-26T14:52:45Z",
                "ephe_filename": "Filename.txt"
            },
            "relationships": {
                "conjunctions": {
                    # Any links or something.
                    "data": [{
                        "type": "Conjunction",
                        "id": "1",
                    },{
                        "type": "Conjunction",
                        "id": "2",
                    }],
                    "links": {
                        "self": "http://localhost:8000/api/reports/838/relationships/conjunctions/",
                        "related": "http://localhost:8000/api/reports/838/conjunctions/"
                    }
                }
            }
        },
    ],
    "meta": {
        "pagination": {
            "page": 1,
            "pages": 84,
            "count": 838
        }
    }
}

请帮忙解决该问题,使输出符合预期。

内容的提问来源于stack exchange,提问作者Paweenwat Maneechai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 18:05:29