Last active
December 15, 2015 14:59
-
-
Save ilovett/5278916 to your computer and use it in GitHub Desktop.
`Tastypie BaseResource to build lists from a queryset` Many to Many relationships in Tastypie Resources require a Manager (9.12 - 9.14), but if you are using a queryset, you can't use the relationship. This base resource allows you to extend your Resources to easily build a pseudo ToMany relationship from your queryset. Special thanks to https:/…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# how the models are related | |
# track -- generic --> audioclips <-- sample | |
class SampledTracksManager(models.Manager): | |
def get_track_samples(self, instance): | |
# must iterate through list because Audioclip object is unscriptable | |
audioclip_ids = [] | |
for audioclip in instance.audioclips.all(): | |
audioclip_ids.append(audioclip.id) | |
# return custom queryset where audioclip_id exists in audioclip_ids built from Track model | |
return Sample.objects.filter(audioclip_id__in=audioclip_ids) | |
class Track(models.Model): | |
objects = SampledTracksManager() | |
# ... model properties ... | |
audioclips = generic.GenericRelation('Audioclip', object_id_field="medium_id", content_type_field="medium_type") | |
def __unicode__(self): | |
return "%s" % (self.title) | |
def get_track_samples(self): | |
return Track.objects.get_track_samples(self) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ResolverResource(ModelResource): | |
def get_reverse_kwargs(self, resolver_type, resource_name=None, resource_id=None, detail_uri_name='pk'): | |
""" | |
Return a dictionary of named URLs included in Tastypie by default. | |
These can be found in tastypie.resources.Resource.base_urls. They | |
are included here as a convenience and a form of documentation. | |
By using this method we can use reverse URL resolution and | |
automatically have all of the kwargs needed by | |
django.core.urlresolvers.reverse to return the URL string. | |
""" | |
if resource_name is None: | |
resource_name = self._meta.resource_name | |
kwargs = { | |
'api_dispatch_list': { | |
'resource_name': resource_name, | |
'api_name': self.api_name | |
}, | |
'api_get_schema': { | |
'resource_name': resource_name, | |
'api_name': self.api_name | |
}, | |
'api_get_multiple': { | |
'resource_name': resource_name, | |
'%s_list' % (detail_uri_name) : resource_id, | |
'api_name': self.api_name | |
}, | |
'api_dispatch_detail': { | |
'resource_name' : resource_name, | |
'%s' % (detail_uri_name) : resource_id, | |
'api_name' : self.api_name | |
} | |
} | |
return kwargs[resolver_type] | |
def get_reverse_uri(self, resolver_type, resource_name=None, resource_id=None): | |
kwargs = self.get_reverse_kwargs(resolver_type, resource_name, resource_id) | |
return reverse(resolver_type, kwargs=kwargs) | |
def get_uri_set(self, ids, resource_name=None): | |
# TODO build a ; delimited string from ids (EG: 1;2;3) and look up 'api_get_multiple' | |
pass | |
def get_uri_list(self, ids, resource_name=None): | |
uri_list = [] | |
for id in ids: | |
uri = self.get_reverse_uri('api_dispatch_detail', resource_name, id) | |
uri_list.append(uri) | |
return uri_list | |
class TrackResource(ResolverResource): | |
album_id = fields.ToOneField('samped.api.resources.AlbumResource', 'album') | |
label_id = fields.ToOneField('samped.api.resources.LabelResource', 'label') | |
artists = fields.ToManyField('samped.api.resources.ArtistResource', 'artists') | |
# have to build uri list from queryset | |
# because tastypie m2m expects a Manager, but querysets for custom querys will crash | |
# track_samples = fields.ToManyField('samped.api.resources.SampleResource', 'get_track_samples') | |
def dehydrate(self, bundle): | |
# have to build uri list from queryset | |
# because tastypie m2m expects a Manager, but querysets for custom querys will crash | |
sample_ids = Track.objects.get_track_samples(bundle.obj).values_list('id', flat=True) | |
# sample_ids = [1, 23, 56] | |
bundle.data['track_samples'] = self.get_uri_list(sample_ids, 'sample') | |
# bundle.data['track_samples'] = ['/api/v1/sample/1/', '/api/v1/sample/23/', '/api/v1/sample/56/'] | |
return bundle | |
class Meta: | |
queryset = Track.objects.all() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment