我正在为空间会合报告创建REST API,我希望会合成为每个报告的子级。
我的模特:
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]
我的网站urls.py
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
时,JSON输出如下所示:
{
"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
时,它给出了conjunctions
的空对象:
{
"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
}
}
}
1条答案
按热度按时间vyswwuz21#
我现在就能解决这个问题。
从现在开始,我将使用
drf-nested-routers
来解析与报表链接相关的合取。您可以通过以下方式安装
不需要在Django项目的www.example.com文件中添加这个库,因为它不包含任何应用、信号或模型。settings.py file, as it does not contain any app, signal or model.
在www.example.com中,添加以下路由器urls.py, add the following routers
在www.example.com中,将
HyperlinkedRelatedField
添加到ReportSerializer
类中。serializers.py, addHyperlinkedRelatedField
intoReportSerializer
class.在www.example.com中,从
ConjunctionViewSet
类覆盖get_queryset
方法以过滤与报告相关的任何合取。views.py, fromConjunctionViewSet
class, overrideget_queryset
method to filter any conjunctions that are related with report.给定的JSON输出结果