这适用于 DRF 3.0。我今天下午刚把这个搞定,如果我遇到任何不可预见的问题,我会跟进(同样,如果你发现任何问题,请告诉我!我对 DRF 还很陌生)
class EnhancedPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
'''
This custom field extends the PrimaryKeyRelatedField
It overrides to_representation (which generates the data to be
serialized) to use a given serializer.
This allows other serializers to show nested data about a related
field, while still allowing the client to set relations by simply
passing an id.
To initialize, pass the queryset and serializer arguments.
The serializer argument should be a Serializer class.
If the serializer provides Meta.model (such as a ModelSerializer),
and you wish to use the queryset provided by that serializer, you may
omit the queryset argument.
e.g.
# without queryset
child_object = EnhancedPrimaryKeyRelatedField(
serializer=ChildObjectSerializer
)
# with queryset
child_object = EnhancedPrimaryKeyRelatedField(
queryset=models.ChildObject.objects.all(),
serializer=SomeSpecializedSerializer
)
'''
def __init__(self, *args, **kwargs):
assert 'serializer' in kwargs
self.serializer = kwargs['serializer']
del kwargs['serializer']
if 'queryset' not in kwargs:
# Catch any programmer errors
assert 'Meta' in self.serializer.__dict__
assert 'model' in self.serializer.Meta.__dict__
kwargs['queryset'] = self.serializer.Meta.model.objects.all()
super(serializers.PrimaryKeyRelatedField, self).__init__(*args, **kwargs)
def to_representation(self, data):
if hasattr(data.pk, 'all'): # are we dealing with a collection?
return self.serializer(data.pk.all(), many=True).data
elif hasattr(data, 'pk') and data.pk:
return self.serializer(self.queryset.get(pk=data.pk)).data
else:
return data.pk