class HousingGroupResource(ModelResource): """HousingGroup Resource""" # exhibit = fields.ToOneField('paws.api.resources.ExhibitResource', 'exhibit') staff = fields.ToManyField('paws.api.resources.StaffResource', 'staff', blank=True) animals = fields.ToManyField('paws.api.resources.AnimalResource', 'animal_set', full=True, blank=True) exhibit = fields.ToOneField('paws.api.resources.ExhibitResource', 'exhibit') class Meta: authentication = CustomAuthentication() authorization = DjangoAuthorization() queryset = models.HousingGroup.objects.all() resource_name = 'housingGroup' always_return_data = True list_allowed_methods = ['get', 'post', 'put', 'patch', 'delete'] # Redefine get_object_list to filter for exhibit_id and staff_id. def get_object_list(self, request): staff_id = request.GET.get('staff_id', None) exhibit_id = request.GET.get('exhibit_id', None) animal_id = request.GET.get('animal_id', None) q_set = super(HousingGroupResource, self).get_object_list(request) # Try filtering by staff_id if it exists. try: staff = models.Staff.objects.get(id=staff_id) q_set = q_set.filter(staff=staff) except ObjectDoesNotExist: pass # Try filtering by exhibit if it exists. try: exhibit = models.Exhibit.objects.get(id=exhibit_id) q_set = q_set.filter(exhibit=exhibit) except ObjectDoesNotExist: pass # Try filtering by animal if it exists try: animal = models.Animal.objects.get(id=animal_id) print animal.housing_group q_set = q_set.filter(id=animal.housing_group.id) except ObjectDoesNotExist: pass return q_set
class PostResource(ModelResource): category = fields.ForeignKey(SubCategoryResource, 'category', full=True, null=True, blank=True) credits = fields.ToManyField( CreditResource, lambda bundle: bundle.obj.credits.order_by('id'), full=True, use_in='detail', null=True, blank=True) tags = fields.ToManyField(TagResource, lambda bundle: bundle.obj.tags.all(), use_in='detail', full=True, null=True, blank=True) images = fields.ToManyField( ImageResource, lambda bundle: bundle.obj.images.order_by('-is_cover', 'id'), full=True, use_in='detail', null=True, blank=True) cover = fields.ToOneField(ImageResource, lambda bundle: Image.objects.filter( post=bundle.obj, is_cover=True).first(), use_in='list', full=True, null=True) class Meta: queryset = Post.objects.order_by('-id') resource_name = 'posts' list_allowed_methods = [ 'get', ] detailed_allowed_methods = [ 'get', ] filtering = { 'category': ALL_WITH_RELATIONS, 'published': ['exact'], 'starred': ['exact'] }
class CategoryResource(ModelResource): children = fields.ToManyField('self', lambda bundle: Category.objects.filter( parent=bundle.obj).order_by('order'), null=True, blank=True, full=True) class Meta: queryset = Category.objects.filter( parent__isnull=True).order_by('order') resource_name = 'category' allowed_methods = ['get'] ordering = [ 'order', ]
class ExhibitResource(ModelResource): """Exhibit Resource.""" housing_groups = fields.ToManyField( 'paws.api.resources.HousingGroupResource', 'housinggroup_set', full=True, blank=True) class Meta: authentication = CustomAuthentication() authorization = DjangoAuthorization() queryset = models.Exhibit.objects.all() resource_name = 'exhibit' always_return_data = True list_allowed_methods = ['get', 'post', 'put', 'delete']
class AdminCategoryResource(ModelResource): children = fields.ToManyField('self', lambda bundle: Category.objects.filter( parent=bundle.obj).order_by('order'), null=True, blank=True, full=True) class Meta: queryset = Category.objects.filter( parent__isnull=True).order_by('order') resource_name = 'categories' list_allowed_methods = ['get', 'post'] detailed_allowed_methods = ['get', 'post', 'put', 'delete'] authentication = MultiAuthentication(BasicAuthentication(), ApiKeyAuthentication()) authorization = DjangoAuthorization()
class AlbumResource(ModelResource): photos = fields.ToManyField(PhotoResource, 'photos', full=True, use_in='detail', null=True) cover = fields.ToOneField( PhotoResource, lambda bundle: Photo.objects.filter(album=bundle.obj).first(), use_in='list', full=True, null=True) class Meta: queryset = Album.objects.order_by('-created_at') resource_name = 'albums' list_allowed_methods = [ 'get', ] detailed_allowed_methods = [ 'get', ] filtering = {'published': ['exact']}
class SplitTransactionResource(ModelResource): total_value = fields.DecimalField(attribute='total_value', default=Decimal(0)) installments = fields.IntegerField(attribute='installments') first_installment_date = fields.DateField() category = fields.ForeignKey(CategoryResource, 'category', full=True, null=True) description = fields.CharField(attribute='description', null=True, blank=True) transactions = fields.ToManyField( TransactionResource, attribute=lambda bundle: Transaction.objects.filter( installment_of=bundle.obj).order_by('installment_number'), full=True, null=True) class Meta: resource_name = "split_transaction" queryset = SplitTransaction.objects.all()\ .annotate(total_value=Sum('transactions__value'))\ .annotate(installments=Count('transactions')) always_return_data = True authentication = MultiAuthentication(SessionAuthentication(), BasicAuthentication()) authorization = UserObjectsOnlyAuthorization() validation = CleanedDataFormValidation( form_class=SplitTransactionApiForm) list_allowed_methods = ['get', 'post'] detail_allowed_methods = ['get'] def _create_installments(self, bundle): """ Creates the installments for this split transaction. """ data = bundle.data transaction_data = { 'value': data.get('total_value') / data.get('installments'), 'date': data.get('first_installment_date'), 'user': bundle.obj.user, 'description': data.get('description'), 'created': timezone.now(), 'category': bundle.obj.category } transactions = [] for i in range(0, data['installments']): transactions.append( Transaction.objects.create(installment_number=(i + 1), **transaction_data)) transaction_data['date'] += relativedelta(months=1) return transactions def hydrate_total_value(self, bundle): value = bundle.data.get('total_value', None) if value: bundle.data['total_value'] = parse_decimal( str(value), locale=bundle.request.locale) return bundle def full_hydrate(self, bundle): bundle = super(SplitTransactionResource, self).full_hydrate(bundle) # this must happen after all hydrations because order isn't garanteed value = bundle.data.get('total_value') if value: # casting value to str to avoid repeating decimals value = Decimal(str(value)).copy_abs() if bundle.obj.category.is_negative: value = value.copy_negate() bundle.data['total_value'] = value return bundle def alter_detail_data_to_serialize(self, request, bundle): data = bundle.data del data['category'] del data['first_installment_date'] return bundle def alter_list_data_to_serialize(self, request, data): for bundle in data['objects']: del bundle.data['category'] del bundle.data['first_installment_date'] return data def obj_create(self, bundle, **kwargs): bundle = super(SplitTransactionResource, self).obj_create(bundle, user=bundle.request.user, **kwargs) bundle.obj.transactions = self._create_installments(bundle) return bundle
class StaffResource(ModelResource): """Staff Resource.""" user = fields.ToOneField('paws.api.resources.UserResource', 'user', full=True) housing_group = fields.ToManyField( 'paws.api.resources.HousingGroupResource', 'housinggroup_set') class Meta: authentication = CustomAuthentication() authorization = DjangoAuthorization() queryset = models.Staff.objects.all() resource_name = 'staff' list_allowed_methods = ['get', 'post', 'put', 'patch', 'delete'] # override the url for a specific url path of searching def override_urls(self): return [ url(r"^(?P<resource_name>%s)\.(?P<format>\w+)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"), ] # determine the format of the returning results in json or xml def determine_format(self, request): if (hasattr(request, 'format') and request.format in self._meta.serializer.formats): return self._meta.serializer.get_mime_for_format(request.format) return super(StaffResource, self).determine_format(request) # wraps the method 'get_seach' so that it can be called in a more functional way def wrap_view(self, view): def wrapper(request, *args, **kwargs): request.format = kwargs.pop('format', None) wrapped_view = super(StaffResource, self).wrap_view(view) return wrapped_view(request, *args, **kwargs) return wrapper # main function for searching def get_search(self, request, **kwargs): # checking user inputs' method self.method_check(request, allowed=['get']) # checking if the user is authenticated self.is_authenticated(request) # checking if the user should be throttled self.throttle_check(request) # Provide the results for a search query sqs = SearchQuerySet().models(models.Staff).load_all().auto_query( request.GET.get('q', '')) paginator = Paginator(sqs, 20) try: page = paginator.page(int(request.GET.get('page', 1))) except InvalidPage: raise Http404("Sorry, no results on that page.") # Create a list of objects that contains the search results objects = [] for result in page.object_list: # create bundle that stores the result object bundle = self.build_bundle(obj=result.object, request=request) # reformating the bundle bundle = self.full_dehydrate(bundle) # adding the bundle into a list of objects objects.append(bundle) # Specifiy the format of json output object_list = { 'objects': objects, } # Handle the recording of the user's access for throttling purposes. self.log_throttled_access(request) # Return the search results in json format return self.create_response(request, object_list) # Redefine get_object_list to filter for animal_id. def get_object_list(self, request): animal_id = request.GET.get('animal_id', None) q_set = super(StaffResource, self).get_object_list(request) #Filtering by animals try: animal = models.Animal.objects.get(id=animal_id) housing_group = animal.housing_group q_set = housing_group.staff.all() except ObjectDoesNotExist: pass return q_set
class ObservationResource(ModelResource): """Observation Resource.""" animal_observations = fields.ToManyField( 'paws.api.resources.AnimalObservationResource', 'animalobservation_set', full=True, null=True, related_name='observation') enrichment = fields.ForeignKey('paws.api.resources.EnrichmentResource', 'enrichment', full=True) staff = fields.ForeignKey('paws.api.resources.StaffResource', 'staff') class Meta: authentication = CustomAuthentication() authorization = Authorization() queryset = models.Observation.objects.all() resource_name = 'observation' list_allowed_methods = ['get', 'post', 'put', 'delete'] # A check to see if staff can modify this observation. def can_modify_observation(self, request, observation_id): # Any superuser can modify an observation. if (request.user.is_superuser): return True try: observation = models.Observation.objects.get(id=observation_id) return observation.staff.user == request.user except ObjectDoesNotExist: return True # creating new observation into database def obj_create(self, bundle, request=None, **kwargs): return super(ObservationResource, self).obj_create(bundle, request, **kwargs) # update observation's information in the database def obj_update(self, bundle, request=None, **kwargs): # Clean related fields into URI's instead of bundles # PATCH fix bundle.data['enrichment'] = bundle.data['enrichment'].data[ 'resource_uri'] for key, animalObservation in enumerate( bundle.data['animal_observations']): bundle.data['animal_observations'][key] = animalObservation.data[ 'resource_uri'] # Make sure that the user can modifty. observation_id = int(kwargs.pop('pk', None)) if not self.can_modify_observation(request, observation_id): raise ImmediateHttpResponse( HttpUnauthorized("Cannot edit other users' observations")) return super(ObservationResource, self).obj_update(bundle, request, **kwargs) # delete observation from the database def obj_delete(self, request=None, **kwargs): # Make sure that the user can modifty. observation_id = int(kwargs.pop('pk', None)) if not self.can_modify_observation(request, observation_id): raise ImmediateHttpResponse( HttpUnauthorized("Cannot edit other users' observations")) return super(ObservationResource, self).obj_delete(request, **kwargs) # Redefine get_object_list to filter for enrichment_id and staff_id. def get_object_list(self, request): show_completed = request.GET.get('show_completed', None) staff_id = request.GET.get('staff_id', None) enrichment_id = request.GET.get('enrichment_id', None) q_set = super(ObservationResource, self).get_object_list(request) # Filter completed observations if not show_completed: q_set = q_set.filter(date_finished__isnull=True) # Try filtering by staff_id if it exists. try: staff = models.Staff.objects.get(id=staff_id) q_set = q_set.filter(staff=staff) except ObjectDoesNotExist: pass # Try filtering by enrichment if it exists. try: enrichment = models.Enrichment.objects.get(id=enrichment_id) q_set = q_set.filter(enrichment=enrichment) except ObjectDoesNotExist: pass return q_set
class AnimalResource(ModelResource): """Animal Resource.""" animal_observations = fields.ToManyField( 'paws.api.resources.AnimalObservationResource', 'animalobservation_set', related_name='animal', blank=True) species = fields.ForeignKey('paws.api.resources.SpeciesResource', 'species', full=True) housing_group = fields.ForeignKey( 'paws.api.resources.HousingGroupResource', 'housing_group', full=False, blank=True) class Meta: queryset = models.Animal.objects.all() authentication = CustomAuthentication() authorization = DjangoAuthorization() resource_name = 'animal' always_return_data = True list_allowed_methods = ['get', 'post', 'put', 'delete'] def obj_create(self, bundle, request=None, **kwargs): if self._meta.authorization.is_authorized(request): return super(AnimalResource, self).obj_create(bundle, request, **kwargs) def obj_update(self, bundle, request=None, **kwargs): return super(AnimalResource, self).obj_update(bundle, request, **kwargs) def obj_delete(self, request=None, **kwargs): return super(AnimalResource, self).obj_delete(request, **kwargs) # override the url for a specific url path of searching def override_urls(self): return [ url(r"^(?P<resource_name>%s)\.(?P<format>\w+)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"), url(r"^(?P<resource_name>%s)/bulk%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('bulk_add'), name="api_bulk_add"), ] # determine the format of the returning results in json or xml def determine_format(self, request): if (hasattr(request, 'format') and request.format in self._meta.serializer.formats): return self._meta.serializer.get_mime_for_format(request.format) return super(AnimalResource, self).determine_format(request) # wraps the method 'get_seach' so that it can be called in a more functional way def wrap_view(self, view): def wrapper(request, *args, **kwargs): request.format = kwargs.pop('format', None) wrapped_view = super(AnimalResource, self).wrap_view(view) return wrapped_view(request, *args, **kwargs) return wrapper # main function for searching def get_search(self, request, **kwargs): # checking user inputs' method self.method_check(request, allowed=['get']) self.is_authenticated(request) self.throttle_check(request) # Provide the results for a search query sqs = SearchQuerySet().models(models.Animal).load_all().auto_query( request.GET.get('q', '')) paginator = Paginator(sqs, 20) try: page = paginator.page(int(request.GET.get('page', 1))) except InvalidPage: raise Http404("Sorry, no results on that page.") # Create a list of objects that contains the search results objects = [] for result in page.object_list: # create bundle that stores the result object bundle = self.build_bundle(obj=result.object, request=request) # reformating the bundle bundle = self.full_dehydrate(bundle) # adding the bundle into a list of objects objects.append(bundle) # Specifiy the format of json output object_list = { 'objects': objects, } # Handle the recording of the user's access for throttling purposes. self.log_throttled_access(request) # Return the search results in json format return self.create_response(request, object_list) # Redefine get_object_list to filter for species_id and/or housingGroup_id def get_object_list(self, request): species_id = request.GET.get('species_id', None) housingGroup_id = request.GET.get('housing_id', None) q_set = super(AnimalResource, self).get_object_list(request) # Try filtering by species if it exists. try: species = models.Species.objects.get(id=species_id) q_set = q_set.filter(species=species) except ObjectDoesNotExist: pass # Try filtering by housingGroup if it exists. try: housinggroup = models.HousingGroup.objects.get(id=housingGroup_id) q_set = q_set.filter(housing_group=housinggroup) except ObjectDoesNotExist: pass return q_set # Bulk add view. def bulk_add(self, request, **kwargs): self.method_check(request, allowed=['post']) self.is_authenticated(request) self.throttle_check(request) # Make sure user is superuser if not request.user.is_superuser: raise ImmediateHttpResponse( HttpUnauthorized("Cannot edit other users' observations")) # try to load the json file try: animal_list = json.loads(request.raw_post_data) except ValueError, e: raise ValueError('Bad JSON: %s' % e) print animal_list # import the data into the database import_animal = bulk_import.importAnimals(animal_list) # build imported animals bundles objects = [] for result in import_animal: # create bundle that stores the result object bundle = self.build_bundle(obj=result, request=request) # reformating the bundle bundle = self.full_dehydrate(bundle) # adding the bundle into a list of objects objects.append(bundle) # Specifiy the format of json output object_list = { 'objects': objects, } return self.create_response(request, object_list)