# by Michal migajek Gajek class NBResource(ModelResource): class Meta: abstract = True # there are three options for specifying filters. # it's either a dictionary of 'filter_name': queryset # or a tuple of filter names # in the second case, if the default_manager attribute is provided # the filter name is assumed to be Manager method, # otherwise it's assumed to be QuerySet method default_manager = None manager_filters = () def prepend_urls(self): """ if there are allowed custom Manager methods, add special url for that""" return [ url(r"^(?P%s)/filtered_list/(?P\w+)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_list_filtered'), name="api_dispatch_list_filtered"), ] if self._meta.manager_filters else [] def dispatch_list_filtered(self, request, **kwargs): """ check if the provided filter name is valid, and - if so - proceed to the get_object_list """ mfilter = kwargs.pop('filter') filters = self._meta.manager_filters if (isinstance(filters, dict) and not mfilter in filters.keys()) or \ not mfilter in filters: raise Exception('Invalid filter (%s) name provided' % filter) request.custom_filter = mfilter return self.dispatch_list(request) def get_object_list(self, request): """ applies custom filtering if the filter name was provided """ if hasattr(request, 'custom_filter'): filters = self._meta.manager_filters if isinstance(filters, dict): # filter to apply is in fact a name of queryset specified in Resource queryset = filters[request.custom_filter]._clone() else: # if there's a default_manager, filter is it's method # otherwise we assume filter is a method of default QuerySet manager_or_queryset = self._meta.default_manager or super(NBResource, self).get_object_list(request) method = getattr(manager_or_queryset, request.custom_filter) if not method: raise Exception('Manager or QuerySet does not have method named %s' % request.custom_filter) #FIXME: very, very ugly trick... kwargs = request.GET.dict() if 'format' in kwargs.keys(): kwargs = deepcopy(kwargs) kwargs.pop('format') queryset = method(**kwargs) else: queryset = super(NBResource, self).get_object_list(request) return queryset #### example usage # scenario one - simple - define filters as querysets directly in the ModelResource class FooResource(NBResource) class Meta: queryset = Foo.objects.all() #standard definition for TastyPie manager_filters = {'active': Foo.objects.filter(active = True) } # calling /api/foo/filtered_list/active # will return only items with active = True attribute # scenario two - complex filtering based on custom Manager's method class FooManager(models.Manager) def recent_active_items(some_parameter) return filteredQuerySet class Foo(models.Model) ... objects = FooManager() class FooResource(NBResource) class Meta: queryset = Foo.objects.all() #standard definition for TastyPie manager_filters = ('recent_active_items',) default_manager = Foo.objects # calling /api/foo/filtered_list/recent_active_items?some_parameter=value # will call FooManager's method with some_parameter as keyword argument