19π
I have been happy with my previous solution, but decided to look again and I think I have another solution that does exactly what you want.
Basically, you need to create your own custom field, and just overwrite the to_representation
method:
class CarpoolField(serializers.PrimaryKeyRelatedField):
def to_representation(self, value):
pk = super(CarpoolField, self).to_representation(value)
try:
item = ParentArrival.objects.get(pk=pk)
serializer = CarpoolSerializer(item)
return serializer.data
except ParentArrival.DoesNotExist:
return None
def get_choices(self, cutoff=None):
queryset = self.get_queryset()
if queryset is None:
return {}
return OrderedDict([(item.id, str(item)) for item in queryset])
class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
carpool = CarpoolField(queryset=Carpool.objects.all())
class Meta:
model = ParentArrival
This will allow you to post with
{
"carpool": 10
}
and get:
{
"carpool": {
"url": "http://localhost:8000/api/school-building-carpools/10/"
"name": "Name of the carpool",
...
}
}
17π
Itβs simple.
As you know, Django appends "_id" to the field name
in the ModelClass, and you can achieve it in the SerializerClass, and the original filed can also be achieved. All you have to do is like this
class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
# ...
carpool_id = serializers.IntegerField(write_only=True)
carpool = SchoolBuildingCarpoolSerializer(read_only=True)
# ...
class Meta:
fields = ('carpool_id', 'carpool', ...)
And use carpool_id
in POST request.
- How to dynamically add EC2 ip addresses to Django ALLOWED_HOSTS
- Setting up proper testing for Django for TDD
- Request input from django custom command?
14π
How about overriding the to_representation
method?
class YourSerializer(serializers.ModelSerializer):
class Meta:
model = ModelClass
fields = ["id", "foreignkey"]
def to_representation(self, instance):
data = super(YourSerializer, self).to_representation(instance)
data['foreignkey'] = YourNestedSerializer(instance.foreignkey).data
return data
- Django formset not validating because ID is required
- How do I restrict access to admin pages in Django?
- FastCGI application behind NGINX is unable to detect that HTTPS secure connection is used
2π
One way to do it is to keep βcarpoolβ as the default you get from DRF, and then add a read-only field for the nested object.
Something like this (I donβt have time to test the code, so consider this pseudo-code. If you cannot get it to work, let me know, and will spend more time):
class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
carpool_info = serializers.SerializerMethodField(read_only=True)
class Meta:
model = ParentArrival
fields = ('id', 'carpool', 'carpool_info',)
def get_carpool_info(self, obj):
carpool = obj.carpool
serializer = SchoolBuildingCarpoolSerializer(carpool)
return serializer.data
If your only nested object is carpool, I would also suggest switching to the regular ModelSerializer so carpool only shows the ID (10) and the nested object then can show the URL.
class ParentArrivalSerializer(serializers.ModelSerializer):
....
and then if it all works, you will be able to do a post with
{
"carpool": 10
}
and your get:
{
"carpool": 10
"carpool_info": {
"url": "http://localhost:8000/api/school-building-carpools/10/"
"name": "Name of the carpool",
...
}
}
I have never found another solution, so this is the trick I have used several times.
- How to serve Django for an Electron app
- Django β Difference between Database backed sessions and Cookie Based Session?
- How do I hide the field label for a HiddenInput widget in Django Admin?
- How to call serializer's create() method from one serializer
- ('Unexpected credentials type', None, 'Expected', 'service_account') with oauth2client (Python)