来自未来的亲爱的朋友:在撰写本文时,Django REST 框架团队似乎正在努力为泛型关系添加更成熟的支持。但它还没有完成。在将此答案复制粘贴到您的代码库之前,请先检查https://github.com/tomchristie/django-rest-framework/pull/755以查看它是否已合并到存储库中。可能有更优雅的解决方案在等着你。——你的远古祖先泰勒
鉴于您使用的是Django REST Framework,如果您确实想做一些后处理(即使您似乎犹豫不决),您可以通过覆盖get_queryset
或list
在您的视图中完成您的目标。像这样的东西:
视图.py:
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from models import *
from itertools import chain
class ResultsList(ListAPIView):
def list(self, request, *args, **kwargs):
nurses = Nurse.objects.all()
pilots = Pilot.objects.all()
results = list()
entries = list(chain(nurses, pilots)) # combine the two querysets
for entry in entries:
type = entry.__class__.__name__.lower() # 'nurse', 'pilot'
if isinstance(entry, Nurse):
serializer = NurseSerializer(entry)
hospital = serializer.data['hospital']
enrollement_date = serializer.data['enrollement.date']
hq = serializer.data['enrollement.hq']
dictionary = {'type': type, 'hospital': hospital, 'hq': hq, 'enrollement_date': enrollement_date}
if isinstance(entry, Pilot):
serializer = PilotSerializer(entry)
plane = serializer.data['plane']
enrollement_date = serializer.data['enrollement.date']
hq = serializer.data['enrollement.hq']
dictionary = {'type': type, 'plane': plane, 'hq': hq, 'enrollement_date': enrollement_date}
results.append(dictionary)
return Response(results)
序列化程序.py
class EnrollementSerializer(serializer.ModelSerializer):
class Meta:
model = Enrollement
fields = ('hq', 'enrollement_date')
class NurseSerializer(serializer.ModelSerializer):
enrollement = EnrollementSerializer(source='enrollement.get')
class Meta:
model = Nurse
fields = ('hospital', 'enrollement')
class PilotSerializer(serializer.ModelSerializer):
enrollement = EnrollementSerializer(source='enrollement.get')
class Meta:
model = Pilot
fields = ('plane', 'enrollement')
返回的响应如下所示:
[
{
type: "nurse",
hq: "http://url/to/hq-detail/view",
enrollement_date: "2003-01-01 01:01:01",
hospital: "http://url/to/hospital-detail/view"
},
{
type: "pilot",
hq: "http://url/to/hq-detail/view",
enrollement_date: "2003-01-01 01:01:01",
plane: "http://url/to/plane-detail/view"
},
]
值得注意的是:
- 我的 serializers.py 在这里可能有点偏离,因为我对如何在序列化程序中表示通用关系的记忆有点模糊。YMMV。
- 与 ^^ 类似,这假设您的 serializers.py 是有序的,并且已根据您的模型正确设置其通用关系。
- 我们这样做是
get
因为source=enrollement.get
如果我们不指定源,则将返回一个 GenericRelatedObjectManager 对象。那是因为这就是泛型关系所代表的。使用.get
强制查询(如在 QuerySet 查询中)访问您设置为通用关系源的模型(在本例中为class Enrollement(models.Model)
.
- 我们必须使用
list(chain())
而不是|
运算符,因为查询集来自不同的模型。这就是我们做不到的原因entries = nurses | pilots
。
for entry in entries
肯定可以做得更干。GLHF。