Skip to content

Instantly share code, notes, and snippets.

@ilovett
Last active December 15, 2015 14:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilovett/5278916 to your computer and use it in GitHub Desktop.
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:/…
# 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)
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