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
相关产品推荐
相关产品推荐

