Reverse relation ToManyField Tastypie
django, json, tastypie
Solution
Use a `ToManyField` instead of ForeignKey and tell it the attribute is `album_set`. To get the full resource to be included, specify `full=True`.
Problem
I have two resources (Tastypie), one of which has a `ToManyField` field: ``` class SongResource(ModelResource): class Meta: queryset = Song.objects.all() resource_name = 'song' authorization = Authorization() class AlbumResource(ModelResource): songs = fields.ToManyField('core.api.SongResource', 'songs', full=True) class Meta: queryset = Album.objects.all() resource_name = 'album' authorization = Authorization() ``` So when I access my PlaylistResource I see something like this : `http://127.0.0.1:8000/api/v1/playlist/1/?format=json` Here is the response I get : ``` { "created_in": "2012-06-24T22:57:01+00:00", "id": "1", "number_of_plays": 0, "playlist_slug": "my-first-playlist", "playlist_title": "my first playlist", "resource_uri": "/api/v1/playlist/1/", "songs": [{ "genre": "Progressive metal", "id": "2", "length": "04:19", "number_of_plays": 0, "price": 0.0, "resource_uri": "/api/v1/song/2/", "song_slug": "leyla-2008", "song_title": "Leyla", "song_url": "http://www.amazon.s3.com/prologue", "thumbnail": "http://almacosta.files.wordpress.com/2011/05/bob_marley.jpg?w=250", "year": 2008 }, { "genre": "Progressive metal", "id": "3", "length": "3.26", "number_of_plays": 0, "price": 0.0, "resource_uri": "/api/v1/song/3/", "song_slug": "yazamadim-2008", "song_title": "Yazamadim", "song_url": "http://www.amazon.s3.com/prologue", "thumbnail": "http://img72.imageshack.us/img72/3215/14so8.jpg", "year": 2008 }] ``` } Now I want to access the album or artist of each song, so I added ``` album = fields.ForeignKey('core.api.AlbumResource','album') ``` to my `SongResource` but I get this error ``` { "error_message": "'Song' object has no attribute 'album'", "traceback": "Traceback (most recent call last):\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 192, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 406, in dispatch_detail\n return self.dispatch('detail', request, **kwargs)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 427, in dispatch\n response = method(request, **kwargs)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 1058, in get_detail\n bundle = self.full_dehydrate(bundle)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 654, in full_dehydrate\n bundle.data[field_name] = field_object.dehydrate(bundle)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/fields.py\", line 709, in dehydrate\n m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource))\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/fields.py\", line 514, in dehydrate_related\n return related_resource.full_dehydrate(bundle)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 654, in full_dehydrate\n bundle.data[field_name] = field_object.dehydrate(bundle)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/fields.py\", line 621, in dehydrate\n foreign_obj = getattr(bundle.obj, self.attribute)\n\nAttributeError: 'Song' object has no attribute 'album'\n" ``` } Is there any trick that allows me to get the reverse data? EDIT Here are my Song and Album models (same order as I have in the models.py file) ``` class Song(models.Model): song_title = models.CharField(max_length=140) length = models.CharField(max_length=5, blank=True, null = True) genre = models.CharField(max_length=100, blank = True, null = True) year = models.IntegerField(blank = True, null = True) thumbnail = models.URLField(default = '/media/thumbnail.png') song_url = models.URLField() number_of_plays = models.IntegerField(verbose_name='Number of plays') price = models.FloatField(default = 0.0) song_slug = models.SlugField(unique=True, max_length=200) def __unicode__(self): return self.song_title class Album(models.Model): album_title = models.CharField(max_length=140) release_year = models.IntegerField('Release Year') price = models.FloatField(default=0.0) album_slug = models.SlugField(unique=True) songs = models.ManyToManyField(Song) def __unicode__(self): return self.album_title def get_absolute_url(self): return '/album/%s' % self.album_slug ```