I believe this tutorial to be best motivated by an example. The example relationships below are from a conference app. A conference app will have presenters (persons) and a schedule with multiple tracks.
api/v1/conference_app/3/?format=json
{ "persons": [ "/api/v1/person/35/", "/api/v1/person/36/" ], "resource_uri": "/api/v1/conference_app/3/", "summary": "test", "tracks": [ "/api/v1/track/6/", "/api/v1/track/7/" ] }
api/v1/conference_app/3/?format=json&inline=true
{ "persons": [ { "conference_id": "/api/v1/conference_app/3/", "description": "", "id": "35", "person_image": null, "person_name": "", "resource_uri": "/api/v1/person/35/" }, { "conference_id": "/api/v1/conference_app/3/", "description": "", "id": "36", "person_image": null, "person_name": "", "resource_uri": "/api/v1/person/36/" } ], "resource_uri": "/api/v1/conference_app/3/", "summary": "test", "tracks": [ { "conference_id": "/api/v1/conference_app/3/", "id": "6", "resource_uri": "/api/v1/track/6/", "schedule_entries": [], "track_name": "test1" }, { "conference_id": "/api/v1/conference_app/3/", "id": "7", "resource_uri": "/api/v1/track/7/", "schedule_entries": [], "track_name": "" } ] }
This tutorial will allow the user of an API to dynamically specify that a resource be either inlined or accessed via a resource_uri.
Tastypie is not capable of changing the fields model values dynamically. The below model inherits from the model ToManyFields which itself inherits from the model Field. Overriding the method dehydrate_related inherited from the model Field allows us to change the dehydration behavior based on the passed in bundle.request.
class ToManyFieldInlineToggle(fields.ToManyField): def dehydrate_related(self, bundle, related_resource): try: isInline = bundle.request.GET.get('inline') if isInline not in [ 'true', 'True', True]: return related_resource.get_resource_uri(bundle) # bundle.request is None except NoneType: pass # Default non-nested behavior bundle = related_resource.build_bundle(obj=related_resource.instance, request=bundle.request) return related_resource.full_dehydrate(bundle)
Then, instead of using field.ToManyField() within your models that inherit from ModelResource, use ToManyFieldInineToggle().