def delete_detail(self, request, **kwargs): " Deleta um curso. " # ETAPA 1 - Desserialização e validação dos dados recebidos # --------------------------------------------------------- course_id = course_id_decoder(kwargs['course_id_solaredx']) deserialized = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json')) deserialized = self.alter_deserialized_detail_data( request, deserialized) bundle = Bundle(data=dict_strip_unicode_keys(deserialized), request=request) bundle.data['course_id'] = course_id validation = CleanedDataFormValidation(form_class=CourseDeleteForm) validation_errors = validation.is_valid(bundle) if validation_errors: raise ImmediateHttpResponse(response=self.error_response( bundle.request, validation_errors)) # ETAPA 2 - Efetuando operações no EDX # ------------------------------------ course_delete(course_id) return http.HttpNoContent()
def dehydrate(self, bundle, for_list=False): print 1 if not bundle.obj or not bundle.obj.pk: print 2 if not self.null: raise ApiFieldError("The model '%r' does not have a primary key and can not be d in a ToMany context." % bundle.obj) return [] if not getattr(bundle.obj, self.attribute): print 3 if not self.null: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't all a null value." % (bundle.obj, self.attribute)) return [] self.m2m_resources = [] m2m_dehydrated = [] # TODO: Also model-specific and leaky. Relies on there being a # ``Manager`` there. # NOTE: only had to remove .all() print 4 for m2m in getattr(bundle.obj, self.attribute): print 5 m2m_resource = self.get_related_resource(m2m) m2m_bundle = Bundle(obj=m2m) self.m2m_resources.append(m2m_resource) # youhou, dirty hack again baby! m2m_bundle.obj = type("DummyContainer", (object,), {'pk': m2m_bundle.obj}) m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource)) return m2m_dehydrated
def _staff_or_instructor_delete_list(self, request, **kwargs): # ETAPA 1 - Desserialização e validação dos dados recebidos # --------------------------------------------------------- course_id = course_id_decoder(kwargs['pk']) staff_or_instructor = kwargs['staff_or_instructor'] deserialized = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json')) deserialized = self.alter_deserialized_detail_data( request, deserialized) bundle = Bundle(data=dict_strip_unicode_keys(deserialized), request=request) if 'user_resource_uri' in bundle.data: user_resource_uri = bundle.data['user_resource_uri'] bundle.data['course_id'] = course_id bundle.data['staff_or_instructor'] = kwargs['staff_or_instructor'] validation = CleanedDataFormValidation(form_class=CourseDeleteUserForm) validation_errors = validation.is_valid(bundle) if validation_errors: raise ImmediateHttpResponse(response=self.error_response( bundle.request, validation_errors)) # ETAPA 2 - Efetuando operações no EDX # ------------------------------------ username = user_resource_uri.split('/')[-2:-1][0] course_remove_user(course_id, username, staff_or_instructor) return http.HttpNoContent()
def dehydrate(self, bundle): foreign_obj = None if isinstance(self.attribute, basestring): attrs = self.attribute.split('__') foreign_obj = bundle.obj for attr in attrs: previous_obj = foreign_obj try: foreign_obj = getattr(foreign_obj, attr, None) except ObjectDoesNotExist: foreign_obj = None elif callable(self.attribute): foreign_obj = self.attribute(bundle) if not foreign_obj: if not self.null: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr)) return None self.fk_resource = self.get_related_resource(foreign_obj) fk_bundle = Bundle(obj=foreign_obj, request=bundle.request) depth = getattr(bundle, 'depth', None) if depth is None: depth = self.max_depth if depth is not None: fk_bundle.depth = depth - 1 return self.dehydrate_related(fk_bundle, self.fk_resource)
def full_dehydrate(self, obj): """ Given an object instance, extract the information from it to populate the resource. """ bundle = Bundle(obj=obj) # Dehydrate each field. for field_name, field_object in self.fields.items(): # A touch leaky but it makes URI resolution work. if isinstance(field_object, RelatedField): field_object.api_name = self._meta.api_name field_object.resource_name = self._meta.resource_name bundle.data[field_name] = field_object.dehydrate(bundle) # Run through optional overrides. for field_name, field_object in self.fields.items(): method = getattr(self, "dehydrate_%s" % field_name, None) if method: bundle.data[field_name] = method(bundle) bundle = self.dehydrate(bundle) return bundle
def post_list(self, request, **kwargs): # ETAPA 1 - Desserialização e validação dos dados recebidos # --------------------------------------------------------- deserialized = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json')) deserialized = self.alter_deserialized_detail_data( request, deserialized) bundle = Bundle(data=dict_strip_unicode_keys(deserialized), request=request) validation = CleanedDataFormValidation(form_class=CourseCreateForm) validation_errors = validation.is_valid(bundle) if validation_errors: raise ImmediateHttpResponse(response=self.error_response( bundle.request, validation_errors)) # ETAPA 2 - Efetuando operações no EDX # ------------------------------------ course_create(bundle.data) # Adicionando ``resource_uri`` bundle.data['resource_uri'] = reverse('api_dispatch_detail', kwargs={ 'api_name': CourseResource._meta.api_name, 'resource_name': CourseResource._meta.resource_name, 'course_id_solaredx': course_id_encoder(bundle.data['course_id'])}) return self.create_response(request, bundle, response_class=http.HttpCreated)
def dehydrate(self, bundle, for_list=True): foreign_obj = None if callable(self.attribute): previous_obj = bundle.obj foreign_obj = self.attribute(bundle) elif isinstance(self.attribute, six.string_types): foreign_obj = bundle.obj for attr in self._attrs: previous_obj = foreign_obj try: foreign_obj = getattr(foreign_obj, attr, None) except ObjectDoesNotExist: foreign_obj = None if not foreign_obj: if not self.null: if callable(self.attribute): raise ApiFieldError("The related resource for resource %s could not be found." % (previous_obj)) else: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr)) return None fk_resource = self.get_related_resource(foreign_obj) fk_bundle = Bundle(obj=foreign_obj, request=bundle.request) fk_bundle.fields = getattr(bundle, 'fields', None) depth = getattr(bundle, 'depth', None) if depth is None: depth = self.max_depth if depth is not None: fk_bundle.depth = depth - 1 return self.dehydrate_related(fk_bundle, fk_resource, for_list=for_list)
def save(self): """ Implements the save method so this form can be used in regular django views. It does the same validation that it usually does for the API, but instead of creating a JSON response, it just creates the object and then returns it. """ assert hasattr(self, 'request') assert self.type == 'create' or self.type == 'update' # Use the form's cleaned_data to create a bundle bundle = Bundle() bundle.data = self.cleaned_data if hasattr(self, 'request'): bundle.request = self.request if hasattr(self, 'instance'): bundle.obj = self.instance # Use the resource's methods to save the bundle self.resource.request = self.request if self.type == 'create': bundle = self.resource.obj_create(bundle) elif self.type == 'update': assert self.request != None assert bundle.obj != None bundle = self.resource.obj_update(bundle, self.request) # Return the object return bundle.obj
def hydrate_lang(self, bundle): translated_bundle = Bundle() translation_resource = I4pProjectTranslationEditResource() for language_code, language_data in bundle.data["lang"].iteritems(): if language_code not in dict(LANGUAGES): continue translated_bundle.data = language_data translated_bundle.obj = bundle.obj.translate(language_code) translation_resource.obj_create(translated_bundle) return bundle
def test_is_valid(self): valid = Validation() bundle = Bundle() self.assertEqual(valid.is_valid(bundle), {}) bundle = Bundle(data={ 'title': 'Foo.', 'slug': 'bar', 'content': '', 'is_active': True, }) self.assertEqual(valid.is_valid(bundle), {})
def test_update_password_with_weak_passwords_returns_error_if_strong_option_on( self): self.domain_obj.strong_mobile_passwords = True self.domain_obj.save() bundle = Bundle() bundle.obj = self.user bundle.data = {"password": '******'} errors = CommCareUserResource._update(bundle) expected_error_message = 'Password is not strong enough. Try making your password more complex.' self.assertIn(expected_error_message, errors)
def dehydrate(self, bundle): if not bundle.obj or not bundle.obj.pk: if not self.null: raise ApiFieldError("The model '%r' does not have a primary key and can not be used in a ToMany context." % bundle.obj) return [] the_m2ms = None previous_obj = bundle.obj attr = self.attribute if isinstance(self.attribute, basestring): attrs = self.attribute.split('__') the_m2ms = bundle.obj for attr in attrs: previous_obj = the_m2ms try: the_m2ms = getattr(the_m2ms, attr, None) except ObjectDoesNotExist: the_m2ms = None if not the_m2ms: break elif callable(self.attribute): the_m2ms = self.attribute(bundle) if not the_m2ms: if not self.null: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr)) return [] self.m2m_resources = [] m2m_dehydrated = [] depth = getattr(bundle, 'depth', None) if depth is None: depth = self.max_depth # TODO: Also model-specific and leaky. Relies on there being a # ``Manager`` there. for m2m in the_m2ms.all(): m2m_resource = self.get_related_resource(m2m) m2m_bundle = Bundle(obj=m2m, request=bundle.request) self.m2m_resources.append(m2m_resource) if depth is not None: m2m_bundle.depth = depth - 1 m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource)) return m2m_dehydrated
def process(self): # Apply envelopes only to HttpResponse returning JSON is_eligible = False if self.response is None and self.content is None: is_eligible = False logger.warning('Envelope initialized without response or raw content') elif self.content and isinstance(self.content, dict): if not(set(['meta', 'data']) < set(self.content.keys())): is_eligible = True else: logger.warning('Attempting to envelope response that is already enveloped') if is_eligible: self.update_data(self.content) elif self.response: content_type = self.response._headers.get('content-type', None) if content_type is not None and 'json' in content_type[1]: original_response_content = json.loads(self.response.content) if 'meta' not in original_response_content or 'data' not in original_response_content: is_eligible = True else: logger.warning('Attempting to envelope response that is already enveloped') if is_eligible: # Load data depending on whether its a list of object or a single object if 'meta' in original_response_content and 'objects' in original_response_content: self.response_data['meta']['pagination'] = original_response_content['meta'] self.update_data(original_response_content['objects']) else: self.update_data(original_response_content) else: logger.warning('Response or data can not be enveloped') if is_eligible: # Load form errors if present if self.validation is not None and isinstance(self.validation, FormValidation): bundle = Bundle() bundle.data = self.response_data['data'] form_errors = self.validation.is_valid(bundle) if form_errors: self.add_errors('form', form_errors) self.set_status(400) self.is_modified = True else: logger.warning('Response or data can not be enveloped') self.is_processed = True
def test_dehydrate(self): note = Note() bundle_1 = Bundle(obj=note) field_1 = ManyToManyField(SubjectResource, 'subjects') field_1.instance_name = 'm2m' try: # self.assertRaises isn't cooperating here. Do it the hard way. field_1.dehydrate(bundle_1) self.fail() except ApiFieldError: pass field_2 = ManyToManyField(SubjectResource, 'subjects', null=True) field_2.instance_name = 'm2m' self.assertEqual(field_2.dehydrate(bundle_1), []) field_3 = ManyToManyField(SubjectResource, 'subjects') field_3.instance_name = 'm2m' bundle_3 = Bundle(obj=self.note_1) self.assertEqual(field_3.dehydrate(bundle_3), ['/api/v1/subjects/1/', '/api/v1/subjects/2/']) field_4 = ManyToManyField(SubjectResource, 'subjects', full=True) field_4.instance_name = 'm2m' bundle_4 = Bundle(obj=self.note_1) subject_bundle_list = field_4.dehydrate(bundle_4) self.assertEqual(len(subject_bundle_list), 2) self.assertEqual(isinstance(subject_bundle_list[0], Bundle), True) self.assertEqual(subject_bundle_list[0].data['name'], u'News') self.assertEqual(subject_bundle_list[0].data['url'], u'/news/') self.assertEqual(subject_bundle_list[0].obj.name, u'News') self.assertEqual(subject_bundle_list[0].obj.url, u'/news/') self.assertEqual(isinstance(subject_bundle_list[1], Bundle), True) self.assertEqual(subject_bundle_list[1].data['name'], u'Photos') self.assertEqual(subject_bundle_list[1].data['url'], u'/photos/') self.assertEqual(subject_bundle_list[1].obj.name, u'Photos') self.assertEqual(subject_bundle_list[1].obj.url, u'/photos/') field_5 = ManyToManyField(SubjectResource, 'subjects') field_5.instance_name = 'm2m' bundle_5 = Bundle(obj=self.note_2) self.assertEqual(field_5.dehydrate(bundle_5), ['/api/v1/subjects/1/', '/api/v1/subjects/3/']) field_6 = ManyToManyField(SubjectResource, 'subjects') field_6.instance_name = 'm2m' bundle_6 = Bundle(obj=self.note_3) self.assertEqual(field_6.dehydrate(bundle_6), [])
def test_update_user_data_returns_error_if_profile_conflict(self): bundle = Bundle() bundle.obj = self.user bundle.data = { 'user_data': { PROFILE_SLUG: self.profile.id, 'conflicting_field': 'no' } } errors = CommCareUserResource._update(bundle) self.assertIn( 'metadata properties conflict with profile: conflicting_field', errors)
def base_context_processor(request): """This is a hook which adds the returned dictionary to the context for every view in the project. It is used to allow the site name to be added to the base_template in every view. Namespace any items added here with 'base_' in order to avoid conflict. """ gconfig = models.GlobalConfig.get() messages = models.Message.objects.filter(route="").filter( Q(status="unread", expires="read") | ~Q(expires="read") ) from iondb.rundb.api import MessageResource resource = MessageResource() msg_list = [resource.full_dehydrate(Bundle(message)) for message in messages] serialized_messages = resource.serialize(None, msg_list, "application/json") base_js_extra = settings.JS_EXTRA if request.user: users = [request.user.username] if request.user.is_staff: users.append(models.Message.USER_STAFF) user_messages = models.Message.objects.filter(route__in=users).filter( Q(status="unread", expires="read") | ~Q(expires="read") ) user_msglist = [ resource.full_dehydrate(Bundle(message)) for message in user_messages ] user_serialized_messages = resource.serialize( None, user_msglist, "application/json" ) unread_news = 0 if settings.FEATURE_FLAGS.NEWS: if request.user.is_authenticated() and gconfig.check_news_posts: unread_news = models.NewsPost.objects.filter( updated__gte=request.user.userprofile.last_read_news_post ).count() return { "base_site_name": gconfig.site_name, "global_messages": serialized_messages, "user_messages": user_serialized_messages, "base_js_extra": base_js_extra, "unread_news": unread_news, "DEBUG": settings.DEBUG, "version": settings.VERSION, "featureflags": settings.FEATURE_FLAGS, }
def test_hydrate(self): note = Note.objects.get(pk=1) bundle = Bundle(obj=note) # With no value, default or nullable, we should get an ``ApiFieldError``. field_1 = ApiField() field_1.instance_name = 'api' self.assertRaises(ApiFieldError, field_1.hydrate, bundle) # The default. field_2 = ApiField(default='foo') field_2.instance_name = 'api' self.assertEqual(field_2.hydrate(bundle), 'foo') # The callable default. def foo(): return 'bar' field_3 = ApiField(default=foo) field_3.instance_name = 'api' self.assertEqual(field_3.hydrate(bundle), 'bar') # The nullable case. field_4 = ApiField(null=True) field_4.instance_name = 'api' self.assertEqual(field_4.hydrate(bundle), None) # The readonly case. field_5 = ApiField(readonly=True) field_5.instance_name = 'api' bundle.data['api'] = 'abcdef' self.assertEqual(field_5.hydrate(bundle), None) # A real, live attribute! field_6 = ApiField(attribute='title') field_6.instance_name = 'api' bundle.data['api'] = note.title self.assertEqual(field_6.hydrate(bundle), u'First Post!') # Make sure it uses attribute when there's no data field_7 = ApiField(attribute='title') field_7.instance_name = 'notinbundle' self.assertEqual(field_7.hydrate(bundle), u'First Post!') # Make sure it falls back to instance name if there is no attribute field_8 = ApiField() field_8.instance_name = 'title' self.assertEqual(field_7.hydrate(bundle), u'First Post!')
def test_is_valid(self): valid = FormValidation(form_class=NoteForm) bundle = Bundle() self.assertEqual( valid.is_valid(bundle), { 'is_active': [u'This field is required.'], 'slug': [u'This field is required.'], '__all__': [u'Having no content makes for a very boring note.'], 'title': [u'This field is required.'], }) bundle = Bundle( data={ 'title': 'Foo.', 'slug': '123456789012345678901234567890123456789012345678901234567890', 'content': '', 'is_active': True, }) self.assertEqual( valid.is_valid(bundle), { 'slug': [u'Ensure this value has at most 50 characters (it has 60).'], '__all__': [u'Having no content makes for a very boring note.'], }) bundle = Bundle(data={ 'title': 'Foo.', 'slug': 'bar', 'content': '', 'is_active': True, }) self.assertEqual(valid.is_valid(bundle), { '__all__': [u'Having no content makes for a very boring note.'], }) bundle = Bundle( data={ 'title': 'Foo.', 'slug': 'bar', 'content': 'This! Is! CONTENT!', 'is_active': True, }) self.assertEqual(valid.is_valid(bundle), {}) # NOTE: Bundle data is left untouched! self.assertEqual(bundle.data['title'], 'Foo.')
def generate_api_key(request, userid): api_key = None try: api_key = ApiKey.objects.get(user=userid) api_key.key = api_key.generate_key() api_key.save() except ApiKey.DoesNotExist: api_key = ApiKey.objects.create(user=userid) # return created key info if api_key is not None: bun = Bundle() bun.data['userid'] = userid bun.data['api_key'] = api_key.key ur = api.resources.UserResource() return HttpResponse(status=201, content=ur.serialize(request, bun, ur.determine_format(request)))
def dehydrate(self, bundle, **kwargs): """ This modified field, allow to include resource_uri of related resources without doing another database query. Using select_related() in resource.meta.queryset also avoids doing extra queries for each object, can be used instead of this class """ if not self.full: pk = getattr(bundle.obj, self.attribute + "_id", None) if not pk: if not self.null: raise ApiFieldError( """The model '%r' has an empty attribute '%s' and doesn't allow a null value.""" % (bundle.obj, self.attribute)) return None # just create a temporal object with only PK temporal_class = type('TemporalModel', (object,), {'pk': pk}) temporal_obj = temporal_class() # from this point, is almost the same stuff that tastypie does. self.fk_resource = self.get_related_resource(temporal_obj) fk_bundle = Bundle( obj=temporal_obj, request=bundle.request) return self.dehydrate_related(fk_bundle, self.fk_resource) return super(OptimizedToOneField, self).dehydrate(bundle, **kwargs)
def test_required_fields(self): bundle = Bundle(data={}) errors = self.validator.is_valid(bundle, None) self.assertIn('data', errors) self.assertIn('required', errors['data'][0])
def test_ci_change_cmdbhistory_registration(self): request = HttpRequest() request.path = self.post_data_cmdb_change['ci'] request.user = self.user request.META['SERVER_NAME'] = 'testserver' request.META['SERVER_PORT'] = 80 cmdb_bundle = Bundle(data=self.post_data_cmdb_change, request=request) cmdb_resource = CIChangeCMDBHistoryResource() cmdb_resource.obj_create(bundle=cmdb_bundle) cmdb_change = None try: cmdb_change = CIChangeCMDBHistory.objects.get( ci_id=self.ci.id, old_value=self.cmdb_old_value, new_value=self.cmdb_new_value) except CIChangeCMDBHistory.DoesNotExist: pass self.assertNotEqual(cmdb_change, None) self.assertEqual( CIChange.objects.filter( object_id=cmdb_change.id, type=chdb.CI_CHANGE_TYPES.CI.id ).count(), 1, )
def dehydrate(self, bundle, for_list=True): foreign_obj = None if callable(self.attribute): previous_obj = bundle.obj foreign_obj = self.attribute(bundle) elif isinstance(self.attribute, six.string_types): foreign_obj = bundle.obj for attr in self._attrs: previous_obj = foreign_obj try: foreign_obj = getattr(foreign_obj, attr, None) except ObjectDoesNotExist: foreign_obj = None if not foreign_obj: if not self.null: if callable(self.attribute): raise ApiFieldError(u"The related resource for resource %s could not be found." % (previous_obj)) else: raise ApiFieldError(u"The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr)) return None fk_resource = self.get_related_resource(foreign_obj) # Up to this point we've copied the code from tastypie 0.13.1. Now # we add caching. cache_key = fk_resource.generate_cache_key('related', pk=foreign_obj.pk, for_list=for_list, ) dehydrated = fk_resource._meta.cache.get(cache_key) if dehydrated is None: fk_bundle = Bundle(obj=foreign_obj, request=bundle.request) dehydrated = self.dehydrate_related(fk_bundle, fk_resource, for_list=for_list) fk_resource._meta.cache.set(cache_key, dehydrated) return dehydrated
def delete_related_detail(self, request, **kwargs): bundle = Bundle(request=request) dataset_id = kwargs.get('dataset_id') story_id = kwargs.pop('story_id', None) asset_id = kwargs.pop('asset_id', None) if asset_id: try: asset = Asset.objects.get(asset_id=asset_id) if not asset.has_perm(bundle.request.user, 'change'): raise ImmediateHttpResponse(response=http.HttpUnauthorized("You are not authorized to change the asset matching the provided asset ID")) except ObjectDoesNotExist: raise ImmediateHttpResponse(response=http.HttpNotFound("An asset matching the provided asset ID could not be found")) elif story_id: try: story = Story.objects.get(story_id=story_id) if not story.has_perm(bundle.request.user, 'change'): raise ImmediateHttpResponse(response=http.HttpUnauthorized("You are not authorized to change the story matching the provided story ID")) except ObjectDoesNotExist: raise ImmediateHttpResponse(response=http.HttpNotFound("A story matching the provided story ID could not be found")) self.obj_get(bundle, dataset_id=dataset_id) if asset_id: asset.datasets.remove(bundle.obj) elif story_id: story.datasets.remove(bundle.obj) return http.HttpNoContent()
def dehydrate(self, bundle, **kwargs): """ If field is configured to only return the resource URI (full=False), a temporal object will be created with only the PK available, this key will be filled with the value saved at self.attribute_id In case, field's self.full is set to True, original dehydrate process will be used. """ if not self.full: pk = getattr(bundle.obj, self.attribute + "_id", None) if not pk: if not self.null: raise ApiFieldError( """The model '%r' has an empty attribute '%s' and doesn't allow a null value.""" % (bundle.obj, self.attribute)) return None # just create a temporal object with only PK temporal_obj = type('TemporalModel', (object,), {'pk': pk})() # from this point, is almost the same stuff that tastypie does. self.fk_resource = self.get_related_resource(temporal_obj) fk_bundle = Bundle( obj=temporal_obj, request=bundle.request) return self.dehydrate_related(fk_bundle, self.fk_resource) return super(OptimizedToOneField, self).dehydrate(bundle, **kwargs)
def build_bundle(self, obj=None, data=None, request=None): """ Given either an object, a data dictionary or both, builds a ``Bundle`` for use throughout the ``dehydrate/hydrate`` cycle. If no object is provided, an empty object from ``Resource._meta.object_class`` is created so that attempts to access ``bundle.obj`` do not fail. In order to maintain consistency between Django and MongoDB documents, it turns the obj's '_id' value into a pk, and adds it as a property on the obj. """ if obj is None: obj = self._meta.object_class() else: obj = self._meta.object_class(obj) if '_id' in obj: if isinstance(obj.get('_id'), ObjectId): obj.pk = obj['_id'].__str__() else: obj.pk = obj['_id'] obj.pop('_id') if data: obj.update(data) return Bundle(obj=obj, data=data, request=request)
def build_related_resource(self, value): """ Used to ``hydrate`` the data provided. If just a URL is provided, the related resource is attempted to be loaded. If a dictionary-like structure is provided, a fresh resource is created. """ self.fk_resource = self.to_class() if isinstance(value, basestring): # We got a URI. Load the object and assign it. try: obj = self.fk_resource.get_via_uri(value) return self.fk_resource.full_dehydrate(obj) except ObjectDoesNotExist: raise ApiFieldError("Could not find the provided object via resource URI '%s'." % value) elif hasattr(value, 'items'): # Try to hydrate the data provided. value = dict_strip_unicode_keys(value) self.fk_bundle = Bundle(data=value) try: return self.fk_resource.obj_update(self.fk_bundle, **value) except NotFound: try: # Attempt lookup by primary key lookup_kwargs = dict((k, v) for k, v in value.iteritems() if getattr(self.fk_resource, k).unique) if not lookup_kwargs: raise NotFound return self.fk_resource.obj_update(self.fk_bundle, **lookup_kwargs) except NotFound: return self.fk_resource.full_hydrate(self.fk_bundle) except MultipleObjectsReturned: return self.fk_resource.full_hydrate(self.fk_bundle) else: raise ApiFieldError("The '%s' field has was given data that was not a URI and not a dictionary-alike: %s." % (self.instance_name, value))
def setUp(self): super(ResourceSerializationTestCase, self).setUp() self.resource = NoteResource() base_bundle = Bundle() self.obj_list = [self.resource.full_dehydrate(self.resource.build_bundle(obj=obj)) for obj in self.resource.obj_get_list(base_bundle)] self.another_resource = AnotherNoteResource() self.another_obj_list = [self.another_resource.full_dehydrate(self.resource.build_bundle(obj=obj)) for obj in self.another_resource.obj_get_list(base_bundle)]
def dehydrate_objects(self, objects): """ Dehydrates each object using the full_dehydrate and then returns the data for each object. This is useful for compound results that return sub objects data. """ return [self.full_dehydrate(Bundle(obj=o)).data for o in objects]
def dehydrate(self, bundle, for_list=True): foreign_obj = None if callable(self.attribute): previous_obj = bundle.obj foreign_obj = self.attribute(bundle) elif isinstance(self.attribute, six.string_types): foreign_obj = bundle.obj for attr in self._attrs: previous_obj = foreign_obj try: foreign_obj = getattr(foreign_obj, attr, None) except ObjectDoesNotExist: foreign_obj = None if not foreign_obj: if not self.null: if callable(self.attribute): raise ApiFieldError("The related resource for resource %s could not be found." % (previous_obj)) else: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr)) return None fk_resource = self.get_related_resource(foreign_obj) fk_bundle = Bundle(obj=foreign_obj, request=bundle.request) return self.dehydrate_related(fk_bundle, fk_resource, for_list=for_list)
def test_dehydrate_with_callable(self): note = Note() bundle_1 = Bundle(obj=self.note_2) field_1 = ToManyField(SubjectResource, attribute=lambda bundle: Subject.objects.filter(notes=bundle.obj, name__startswith='Personal')) field_1.instance_name = 'm2m' self.assertEqual(field_1.dehydrate(bundle_1), ['/api/v1/subjects/3/'])
def test_dehydrate(self): note = Note.objects.get(pk=1) bundle = Bundle(obj=note) # With no attribute or default, we should get ``None``. field_1 = ApiField() self.assertEqual(field_1.dehydrate(bundle), None) # Still no attribute, so we should pick up the default field_2 = ApiField(default=True) self.assertEqual(field_2.dehydrate(bundle), True) # Wrong attribute should yield default. field_3 = ApiField(attribute='foo', default=True) self.assertEqual(field_3.dehydrate(bundle), True) # Wrong attribute should yield null. field_4 = ApiField(attribute='foo', null=True) self.assertEqual(field_4.dehydrate(bundle), None) # Correct attribute. field_5 = ApiField(attribute='title', default=True) self.assertEqual(field_5.dehydrate(bundle), u'First Post!') # Correct callable attribute. field_6 = ApiField(attribute='what_time_is_it', default=True) self.assertEqual(field_6.dehydrate(bundle), datetime.datetime(2010, 4, 1, 0, 48))
def get_via_uri(self, uri, request=None): """ This pulls apart the salient bits of the URI and populates the resource via a ``obj_get``. Optionally accepts a ``request``. If you need custom behavior based on other portions of the URI, simply override this method. """ prefix = get_script_prefix() chomped_uri = uri if prefix and chomped_uri.startswith(prefix): chomped_uri = chomped_uri[len(prefix) - 1:] try: view, args, kwargs = resolve(chomped_uri) resource_name = kwargs['resource_name'] resource_class = self.resource_mapping[resource_name] except (Resolver404, KeyError): raise NotFound("The URL provided '%s' was not a link to a valid resource." % uri) parent_resource = resource_class(api_name=self._meta.api_name) kwargs = parent_resource.remove_api_resource_names(kwargs) bundle = Bundle(request=request) return parent_resource.obj_get(bundle, **kwargs)
def dehydrate(self, bundle, for_list=False): foreign_obj = None if isinstance(self.attribute, basestring): attrs = self.attribute.split('__') foreign_obj = bundle.obj for attr in attrs: previous_obj = foreign_obj try: foreign_obj = getattr(foreign_obj, attr, None) except ObjectDoesNotExist: foreign_obj = None elif callable(self.attribute): foreign_obj = self.attribute(bundle) if not foreign_obj: if not self.null: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr)) return None if has_related_request(bundle): self.fk_resource = self.get_related_resource(foreign_obj) fk_bundle = Bundle(obj=foreign_obj, request=bundle.request) return self.dehydrate_related(fk_bundle, self.fk_resource) else: return super(JailToOneField, self).dehydrate(bundle)
def obj_create(self, bundle, request, **kwargs): with statsd.timer('auth.browserid.verify'): profile, msg = browserid_authenticate( request, bundle.data['assertion'], browserid_audience=bundle.data['audience'], is_native=bundle.data.get('is_native', False)) if profile is None: log.info('No profile') raise http_error(http.HttpUnauthorized, 'No profile.') request.user, request.amo_user = profile.user, profile request.groups = profile.groups.all() # TODO: move this to the signal. profile.log_login_attempt(True) user_logged_in.send(sender=profile.user.__class__, request=request, user=profile.user) bundle.data = { 'error': None, 'token': self.get_token(request.user.email), 'settings': { 'display_name': request.amo_user.display_name, 'email': request.user.email, } } bundle.data.update(PermissionResource().dehydrate( Bundle(request=request)).data) return bundle
def update(request): """provide a simple interface to allow Torrent Suite to be updated""" if request.method == "POST": updateLocked = run_update() data = json.dumps({"lockBlocked": updateLocked}) return http.HttpResponse(data, content_type="application/json") elif request.method == "GET": about, meta_version = findVersions() config = GlobalConfig.get() from iondb.rundb.api import GlobalConfigResource resource = GlobalConfigResource() bundle = Bundle(config) serialized_config = resource.serialize(None, resource.full_dehydrate(bundle), "application/json") return render_to_response( "admin/update.html", { "about": about, "meta": meta_version, "global_config": serialized_config }, RequestContext(request, {}), )
def dehydrate(self, bundle): if not bundle.obj or not bundle.obj.pk: if not self.null: raise ApiFieldError("The model '%r' does not have a primary key and can not be used in a ToMany context." % bundle.obj) return [] if not getattr(bundle.obj, self.attribute): if not self.null: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (bundle.obj, self.attribute)) return [] self.m2m_resources = [] m2m_dehydrated = [] # TODO: Also model-specific and leaky. Relies on there being a # ``Manager`` there. for m2m in getattr(bundle.obj, self.attribute).all(): m2m_resource = self.get_related_resource(m2m) m2m_bundle = Bundle(obj=m2m) self.m2m_resources.append(m2m_resource) m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource)) return m2m_dehydrated
def dehydrate(self, bundle, for_list=True): if not bundle.obj or not bundle.obj.pk: if not self.null: raise ApiFieldError( "The model '%r' does not have a primary key and can not " "be used in a ToMany context." % bundle.obj, ) return [] the_m2ms = None if isinstance(self.attribute, basestring): the_m2ms = getattr(bundle.obj, self.attribute) elif callable(self.attribute): the_m2ms = self.attribute(bundle) if not the_m2ms: if not self.null: raise ApiFieldError( "The model '%r' has an empty attribute '%s' and doesn't " "allow a null value." % (bundle.obj, self.attribute), ) return [] self.m2m_resources = [] m2m_dehydrated = [] for m2m in the_m2ms.filter(*self.filter_args_func(), **self.filter_kwargs_func()): m2m_resource = self.get_related_resource(m2m) m2m_bundle = Bundle(obj=m2m, request=bundle.request) self.m2m_resources.append(m2m_resource) m2m_dehydrated.append( self.dehydrate_related(m2m_bundle, m2m_resource, for_list), ) return m2m_dehydrated
def import_layer(self, request, **kwargs): """ Imports a layer """ self.method_check(request, allowed=['post']) b = Bundle() b.request = request try: obj = self.obj_get(b, pk=kwargs.get('pk')) except UploadLayer.DoesNotExist: raise ImmediateHttpResponse(response=http.HttpNotFound()) configuration_options = request.POST.get('configurationOptions') if 'application/json' in request.META.get('CONTENT_TYPE', ''): configuration_options = json.loads(request.body) if isinstance(configuration_options, list) and len(configuration_options) == 1: configuration_options = configuration_options[0] if isinstance(configuration_options, dict): self.clean_configuration_options(request, obj, configuration_options) obj.configuration_options = configuration_options obj.save() if not configuration_options: raise ImmediateHttpResponse( response=http.HttpBadRequest('Configuration options missing.')) request_cookies = request.COOKIES uploaded_file = obj.upload.uploadfile_set.first() import_result = import_object.delay( uploaded_file.id, configuration_options=configuration_options, request_cookies=request_cookies, request_user=request.user) # query the db again for this object since it may have been updated during the import obj = self.obj_get(b, pk=kwargs.get('pk')) obj.task_id = import_result.id obj.save() return self.create_response(request, {'task': obj.task_id})
def dehydrate(self, bundle): if not bundle.obj or not bundle.obj.pk: if not self.null: raise ApiFieldError("The model '%r' does not have a primary \ key and can not be used in a ToMany context." % bundle.obj) return [] the_m2ms = None previous_obj = bundle.obj attr = self.attribute if isinstance(self.attribute, basestring): attrs = self.attribute.split('__') the_m2ms = bundle.obj for attr in attrs: previous_obj = the_m2ms try: the_m2ms = getattr(the_m2ms, attr, None) the_m2ms = self.apply_m2m_filters(bundle.request, attr, the_m2ms.all()) except ObjectDoesNotExist: the_m2ms = None if not the_m2ms: break try: the_m2ms = self.apply_sorting(bundle.request, the_m2ms.all()) except InvalidSortError: pass elif callable(self.attribute): the_m2ms = self.attribute(bundle) if not the_m2ms: if not self.null: raise ApiFieldError("The model '%r' has an empty attribute \ '%s' and doesn't allow a null value." % (previous_obj, attr)) return [] self.m2m_resources = [] m2m_dehydrated = [] # TODO: Also model-specific and leaky. Relies on there being a # ``Manager`` there. for m2m in the_m2ms.select_related(): m2m_resource = self.get_related_resource(m2m) m2m_bundle = Bundle(obj=m2m, request=bundle.request) self.m2m_resources.append(m2m_resource) m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource)) return m2m_dehydrated
def dehydrate(self, bundle, for_list=True): if not bundle.obj or not bundle.obj.pk: if not self.null: raise ApiFieldError( "The model '%r' does not have a primary key and can not be used in a ToMany context." % bundle.obj) return [] the_m2ms = None previous_obj = bundle.obj attr = self.attribute if isinstance(self.attribute, six.string_types): attrs = self.attribute.split('__') the_m2ms = bundle.obj for attr in attrs: previous_obj = the_m2ms try: the_m2ms = getattr(the_m2ms, attr, None) except ObjectDoesNotExist: the_m2ms = None if not the_m2ms: break elif callable(self.attribute): the_m2ms = self.attribute(bundle) if not the_m2ms: if not self.null: raise ApiFieldError( "The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr)) return [] self.m2m_resources = [] m2m_dehydrated = [] # TODO: Also model-specific and leaky. Relies on there being a # ``Manager`` there. the_m2ms_list = the_m2ms.all() if self.filter: the_m2ms_list = the_m2ms_list.filter(**filter) if self.limit: the_m2ms_list = the_m2ms_list[0:self.limit] for m2m in the_m2ms_list: m2m_resource = self.get_related_resource(m2m) m2m_bundle = Bundle(obj=m2m, request=bundle.request) self.m2m_resources.append(m2m_resource) m2m_dehydrated.append( self.dehydrate_related(m2m_bundle, m2m_resource, for_list=for_list)) return m2m_dehydrated
def test_to_native(self): resource = AppResource().full_dehydrate(Bundle(obj=self.app)) native = self.field.to_native(self.membership) for key, value in native.iteritems(): if key == 'resource_uri': eq_(value, self.app.get_api_url(pk=self.app.pk)) else: eq_(value, resource.data[key])
def delete_detail(self, request, **kwargs): from freenasUI.freeadmin.navtree import navtree bundle = Bundle(request=request) bundle.obj = self.obj_get(bundle=bundle, **self.remove_api_resource_names(kwargs)) if bundle.obj._meta.model._admin.delete_form: deserialized = self.deserialize( request, request.body or '{}', format=request.META.get('CONTENT_TYPE', 'application/json'), ) Form = __import__( f'{bundle.obj._meta.app_label}.forms', globals(), locals(), [bundle.obj._meta.model._admin.delete_form], 0, ) Form = getattr(Form, bundle.obj._meta.model._admin.delete_form) form = Form(data=deserialized, instance=bundle.obj) if not form.is_valid(): raise ImmediateHttpResponse( response=self.error_response(request, form.errors) ) # Grab the form to call delete on same as in freeadmin m = bundle.obj._meta.model mf = None if not isinstance(navtree._modelforms[m], dict): mf = navtree._modelforms[m] else: if mf is None: try: mf = navtree._modelforms[m][m._admin.edit_modelform] except Exception: mf = list(navtree._modelforms[m].values())[-1] else: mf = navtree._modelforms[m][mf] if mf: form = mf(instance=bundle.obj) form.delete() return http.HttpNoContent() else: return super().delete_detail(request, **kwargs)
def test_hydrate(self): note = Note() bundle = Bundle(obj=note) # With no value or nullable, we should get an ``ApiFieldError``. field_1 = ForeignKey(UserResource, 'author') self.assertRaises(ApiFieldError, field_1.hydrate, bundle) note = Note.objects.get(pk=1) bundle = Bundle(obj=note) # The nullable case. field_2 = ForeignKey(UserResource, 'author', null=True) field_2.instance_name = 'fk' bundle.data['fk'] = None self.assertEqual(field_2.hydrate(bundle), None) # Wrong resource URI. field_3 = ForeignKey(UserResource, 'author') field_3.instance_name = 'fk' bundle.data['fk'] = '/api/v1/users/abc/' self.assertRaises(NotFound, field_3.hydrate, bundle) # A real, live attribute! field_4 = ForeignKey(UserResource, 'author') field_4.instance_name = 'fk' bundle.data['fk'] = '/api/v1/users/1/' fk_bundle = field_4.hydrate(bundle) self.assertEqual(fk_bundle.data['username'], u'johndoe') self.assertEqual(fk_bundle.data['email'], u'*****@*****.**') self.assertEqual(fk_bundle.obj.username, u'johndoe') self.assertEqual(fk_bundle.obj.email, u'*****@*****.**') field_5 = ForeignKey(UserResource, 'author') field_5.instance_name = 'fk' bundle.data['fk'] = { 'username': u'mistersmith', 'email': u'*****@*****.**', 'password': u'foobar', } fk_bundle = field_5.hydrate(bundle) self.assertEqual(fk_bundle.data['username'], u'mistersmith') self.assertEqual(fk_bundle.data['email'], u'*****@*****.**') self.assertEqual(fk_bundle.obj.username, u'mistersmith') self.assertEqual(fk_bundle.obj.email, u'*****@*****.**') # Regression - Make sure Unicode keys get converted to regular strings # so that we can **kwargs them. field_6 = ForeignKey(UserResource, 'author') field_6.instance_name = 'fk' bundle.data['fk'] = { u'username': u'mistersmith', u'email': u'*****@*****.**', u'password': u'foobar', } fk_bundle = field_6.hydrate(bundle) self.assertEqual(fk_bundle.data['username'], u'mistersmith') self.assertEqual(fk_bundle.data['email'], u'*****@*****.**') self.assertEqual(fk_bundle.obj.username, u'mistersmith') self.assertEqual(fk_bundle.obj.email, u'*****@*****.**')
def dehydrate(self, bundle): try: foreign_obj = getattr(bundle.obj, self.attribute) except ObjectDoesNotExist: foreign_obj = None if not foreign_obj: if not self.null: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (bundle.obj, self.attribute)) return None self.fk_resource = self.get_related_resource(foreign_obj) fk_bundle = Bundle(obj=foreign_obj, request=bundle.request) # add by zzgvh if getattr(bundle, 'related_info', False): fk_bundle.related_info = bundle_related_data_info_factory(parent_bundle=bundle) # end add return self.dehydrate_related(fk_bundle, self.fk_resource)
def dehydrate(self, bundle): if self.attribute is not None: obj = getattr(bundle.obj, self.attribute) final_fields = _get_fields(obj) schema = obj.schema() # Run through the list and dehydrate each item obj_data = {} for key, item in obj.iteritems(): obj_bundle = Bundle(item) for field_name, field_object in final_fields.iteritems(): obj_bundle.data[field_name] = field_object.dehydrate(obj_bundle) obj_data[key] = obj_bundle.data return self.convert(obj_data) if self.has_default(): return self.convert(self.default) else: return None
def import_layer(self, request, **kwargs): """ Imports a layer """ self.method_check(request, allowed=['post']) b = Bundle() b.request = request try: obj = self.obj_get(b, pk=kwargs.get('pk')) except UploadLayer.DoesNotExist: raise ImmediateHttpResponse(response=http.HttpNotFound()) configuration_options = request.POST.get('configurationOptions') if 'application/json' in request.META.get('CONTENT_TYPE', ''): configuration_options = json.loads(request.body) if isinstance(configuration_options, list) and len(configuration_options) == 1: configuration_options = configuration_options[0] if isinstance(configuration_options, dict): self.clean_configuration_options(request, obj, configuration_options) obj.configuration_options = configuration_options obj.save() if not configuration_options: raise ImmediateHttpResponse(response=http.HttpBadRequest('Configuration options missing.')) request_cookies = request.COOKIES uploaded_file = obj.upload.uploadfile_set.first() import_result = import_object.delay(uploaded_file.id, configuration_options=configuration_options, request_cookies=request_cookies, request_user=request.user) # query the db again for this object since it may have been updated during the import obj = self.obj_get(b, pk=kwargs.get('pk')) obj.task_id = import_result.id obj.save() return self.create_response(request, {'task': obj.task_id})
def test_hydrate(self): note = Note.objects.get(pk=1) bundle = Bundle(obj=note) # With no value, default or nullable, we should get an ``ApiFieldError``. field_1 = ApiField() field_1.instance_name = "api" self.assertRaises(ApiFieldError, field_1.hydrate, bundle) # The default. field_2 = ApiField(default="foo") field_2.instance_name = "api" self.assertEqual(field_2.hydrate(bundle), "foo") # The callable default. def foo(): return "bar" field_3 = ApiField(default=foo) field_3.instance_name = "api" self.assertEqual(field_3.hydrate(bundle), "bar") # The nullable case. field_4 = ApiField(null=True) field_4.instance_name = "api" self.assertEqual(field_4.hydrate(bundle), None) # The readonly case. field_5 = ApiField(readonly=True) field_5.instance_name = "api" bundle.data["api"] = "abcdef" self.assertEqual(field_5.hydrate(bundle), None) # A real, live attribute! field_6 = ApiField(attribute="title") field_6.instance_name = "api" bundle.data["api"] = note.title self.assertEqual(field_6.hydrate(bundle), u"First Post!")
def dehydrate(self, bundle): if not bundle.obj or not hasattr(bundle.obj, 'pk'): if not self.null: raise ApiFieldError("The model '%r' does not have a primary key and can not be d in a ToMany context." % bundle.obj) return [] if not getattr(bundle.obj, self.attribute): if not self.null: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't all a null value." % (bundle.obj, self.attribute)) return [] self.m2m_resources = [] m2m_dehydrated = [] # TODO: Also model-specific and leaky. Relies on there being a # ``Manager`` there. # NOTE: only had to remove .all() for index, m2m in enumerate(getattr(bundle.obj, self.attribute)): m2m.pk = index m2m.parent = bundle.obj m2m_resource = self.get_related_resource(m2m) m2m_bundle = Bundle(obj=m2m) self.m2m_resources.append(m2m_resource) m2m_bundle.request = bundle.request m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource)) return m2m_dehydrated
def dehydrate(self, bundle): if not bundle.obj or not bundle.obj.pk: if not self.null: raise ApiFieldError("The model '%r' does not have a primary key and can not be used in a ToMany context." % bundle.obj) return [] the_m2ms = None if isinstance(self.attribute, basestring): the_m2ms = getattr(bundle.obj, self.attribute) elif callable(self.attribute): the_m2ms = self.attribute(bundle) if not the_m2ms: if not self.null: raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (bundle.obj, self.attribute)) return [] self.m2m_resources = [] m2m_dehydrated = [] # TODO: Also model-specific and leaky. Relies on there being a # ``Manager`` there. for m2m in the_m2ms.all(): m2m_resource = self.get_related_resource(m2m) m2m_bundle = Bundle(obj=m2m, request=bundle.request) # add by zzgvh if getattr(bundle, 'related_info', False): m2m_bundle.related_info = bundle_related_data_info_factory(parent_bundle=bundle) # end add self.m2m_resources.append(m2m_resource) m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource)) return m2m_dehydrated
def import_layer(self, request, **kwargs): """ Imports a layer """ self.method_check(request, allowed=["post"]) b = Bundle() b.request = request try: obj = self.obj_get(b, pk=kwargs.get("pk")) except UploadLayer.DoesNotExist: raise ImmediateHttpResponse(response=http.HttpNotFound()) configuration_options = request.POST.get("configurationOptions") if "application/json" in request.META.get("CONTENT_TYPE", ""): configuration_options = json.loads(request.body) if isinstance(configuration_options, dict): obj.configuration_options = configuration_options obj.save() configuration_options = [configuration_options] if not configuration_options: raise ImmediateHttpResponse(response=http.HttpBadRequest("Configuration options missing.")) uploaded_file = obj.upload.uploadfile_set.first() import_result = import_object.delay(uploaded_file.id, configuration_options=configuration_options) # query the db again for this object since it may have been updated during the import obj = self.obj_get(b, pk=kwargs.get("pk")) obj.task_id = import_result.id obj.save() return self.create_response(request, {"task": obj.task_id})
def test_hydrate(self): note = Note.objects.get(pk=1) bundle = Bundle(obj=note) # With no value or nullable, we should get an ``ApiFieldError``. field_1 = ForeignKey(UserResource, "author") self.assertRaises(ApiFieldError, field_1.hydrate, bundle) # The nullable case. field_2 = ForeignKey(UserResource, "author", null=True) field_2.instance_name = "fk" bundle.data["fk"] = None self.assertEqual(field_2.hydrate(bundle), None) # Wrong resource URI. field_3 = ForeignKey(UserResource, "author") field_3.instance_name = "fk" bundle.data["fk"] = "/api/v1/users/abc/" self.assertRaises(NotFound, field_3.hydrate, bundle) # A real, live attribute! field_4 = ForeignKey(UserResource, "author") field_4.instance_name = "fk" bundle.data["fk"] = "/api/v1/users/1/" fk_bundle = field_4.hydrate(bundle) self.assertEqual(fk_bundle.data["username"], u"johndoe") self.assertEqual(fk_bundle.data["email"], u"*****@*****.**") self.assertEqual(fk_bundle.obj.username, u"johndoe") self.assertEqual(fk_bundle.obj.email, u"*****@*****.**") field_5 = ForeignKey(UserResource, "author") field_5.instance_name = "fk" bundle.data["fk"] = {"username": u"mistersmith", "email": u"*****@*****.**", "password": u"foobar"} fk_bundle = field_5.hydrate(bundle) self.assertEqual(fk_bundle.data["username"], u"mistersmith") self.assertEqual(fk_bundle.data["email"], u"*****@*****.**") self.assertEqual(fk_bundle.obj.username, u"mistersmith") self.assertEqual(fk_bundle.obj.email, u"*****@*****.**") # Regression - Make sure Unicode keys get converted to regular strings # so that we can **kwargs them. field_6 = ForeignKey(UserResource, "author") field_6.instance_name = "fk" bundle.data["fk"] = {u"username": u"mistersmith", u"email": u"*****@*****.**", u"password": u"foobar"} fk_bundle = field_6.hydrate(bundle) self.assertEqual(fk_bundle.data["username"], u"mistersmith") self.assertEqual(fk_bundle.data["email"], u"*****@*****.**") self.assertEqual(fk_bundle.obj.username, u"mistersmith") self.assertEqual(fk_bundle.obj.email, u"*****@*****.**")
def test_vocabulary_validation(self): vv = VocabularyValidation() request = RequestFactory() request.course = self.sample_course mock_bundle = Bundle() mock_bundle.data['display_name'] = 'Shapes' mock_bundle.request = request errors = vv.is_valid(mock_bundle) self.assertTrue('error_message' in errors) self.assertTrue( 'A Shapes concept exists' in errors['error_message'][0]) mock_bundle = Bundle() mock_bundle.data['display_name'] = 'Patterns' mock_bundle.data['object_id'] = self.sample_course.id mock_bundle.request = request errors = vv.is_valid(mock_bundle) self.assertFalse('error_message' in errors)
def test_hydrate(self): note = Note() bundle = Bundle(obj=note) # With no value or nullable, we should get an ``ApiFieldError``. field_1 = ToOneField(UserResource, 'author') self.assertRaises(ApiFieldError, field_1.hydrate, bundle) note = Note.objects.get(pk=1) bundle = Bundle(obj=note) # The nullable case. field_2 = ToOneField(UserResource, 'author', null=True) field_2.instance_name = 'fk' bundle.data['fk'] = None self.assertEqual(field_2.hydrate(bundle), None) # Wrong resource URI. field_3 = ToOneField(UserResource, 'author') field_3.instance_name = 'fk' bundle.data['fk'] = '/api/v1/users/abc/' self.assertRaises(NotFound, field_3.hydrate, bundle) # A real, live attribute! field_4 = ToOneField(UserResource, 'author') field_4.instance_name = 'fk' bundle.data['fk'] = '/api/v1/users/1/' fk_bundle = field_4.hydrate(bundle) self.assertEqual(fk_bundle.data['username'], u'johndoe') self.assertEqual(fk_bundle.data['email'], u'*****@*****.**') self.assertEqual(fk_bundle.obj.username, u'johndoe') self.assertEqual(fk_bundle.obj.email, u'*****@*****.**') field_5 = ToOneField(UserResource, 'author') field_5.instance_name = 'fk' bundle.data['fk'] = { 'username': u'mistersmith', 'email': u'*****@*****.**', 'password': u'foobar', } fk_bundle = field_5.hydrate(bundle) self.assertEqual(fk_bundle.data['username'], u'mistersmith') self.assertEqual(fk_bundle.data['email'], u'*****@*****.**') self.assertEqual(fk_bundle.obj.username, u'mistersmith') self.assertEqual(fk_bundle.obj.email, u'*****@*****.**') # Regression - Make sure Unicode keys get converted to regular strings # so that we can **kwargs them. field_6 = ToOneField(UserResource, 'author') field_6.instance_name = 'fk' bundle.data['fk'] = { u'username': u'mistersmith', u'email': u'*****@*****.**', u'password': u'foobar', } fk_bundle = field_6.hydrate(bundle) self.assertEqual(fk_bundle.data['username'], u'mistersmith') self.assertEqual(fk_bundle.data['email'], u'*****@*****.**') self.assertEqual(fk_bundle.obj.username, u'mistersmith') self.assertEqual(fk_bundle.obj.email, u'*****@*****.**') # Attribute & null regression test. # First, simulate data missing from the bundle & ``null=True``. # Use a Note with NO author, so that the lookup for the related # author fails. note = Note.objects.create( title='Biplanes for all!', slug='biplanes-for-all', content='Somewhere, east of Manhattan, will lie the mythical land of planes with more one wing...' ) bundle = Bundle(obj=note) field_7 = ToOneField(UserResource, 'notinbundle', null=True) field_7.instance_name = 'notinbundle' self.assertEqual(field_7.hydrate(bundle), None) # Then do something in the bundle also with ``null=True``. field_8 = ToOneField(UserResource, 'author', null=True) field_8.instance_name = 'author' fk_bundle = field_8.hydrate(bundle) self.assertEqual(field_8.hydrate(bundle), None) # Then use an unsaved object in the bundle also with ``null=True``. new_note = Note( title='Biplanes for all!', slug='biplanes-for-all', content='Somewhere, east of Manhattan, will lie the mythical land of planes with more one wing...' ) new_bundle = Bundle(obj=new_note) field_9 = ToOneField(UserResource, 'author', null=True) field_9.instance_name = 'author' self.assertEqual(field_9.hydrate(bundle), None) # The blank case. field_10 = ToOneField(UserResource, 'fk', blank=True) field_10.instance_name = 'fk' self.assertEqual(field_10.hydrate(bundle), None) bundle.data['author'] = '/api/v1/users/1/' field_11 = ToOneField(UserResource, 'author', blank=True) field_11.instance_name = 'author' fk_bundle = field_11.hydrate(bundle) self.assertEqual(fk_bundle.obj.username, 'johndoe') # The readonly case. field_12 = ToOneField(UserResource, 'author', readonly=True) field_12.instance_name = 'author' self.assertEqual(field_12.hydrate(bundle), None) # A related object. field_13 = ToOneField(UserResource, 'author') field_13.instance_name = 'fk' bundle.related_obj = User.objects.get(pk=1) bundle.related_name = 'author' fk_bundle = field_13.hydrate(bundle) self.assertEqual(fk_bundle.obj.username, u'johndoe') self.assertEqual(fk_bundle.obj.email, u'*****@*****.**')
def image_upload(self, request, **kwargs): """ Special handler function to create a project based on search criteria from images """ json_data = simplejson.loads(request.body) deployments = {} #pull the query parameters out for i in range(0, len(json_data['objects']),1): deployment = json_data['objects'][i]['deployment'] deployment_id = deployment.split('/')[len(deployment.split('/'))-2] #dp = None #if deployment_id in deployments.keys(): # dp = deployments[deployment_id] #else: # dp = Deployment.objects.filter(id=int(deployment_id)) #create the Image image_bundle = Bundle() image_bundle.request = request image_name = json_data['objects'][i]['image_name'] date_time = json_data['objects'][i]['date_time'] position = json_data['objects'][i]['position'] depth = json_data['objects'][i]['depth'] depth_uncertainty = json_data['objects'][i]['depth_uncertainty'] dpc = None if (depth_uncertainty is not None and depth_uncertainty != 'null'): dpc = float(depth_uncertainty) image_bundle.data = dict(deployment=deployment, image_name=image_name, date_time=date_time, position=position, depth=depth, depth_uncertainty=dpc) new_image = self.obj_create(image_bundle) #create Measurement temperature = json_data['objects'][i]['temperature'] temperature_unit = json_data['objects'][i]['temperature_unit'] salinity = json_data['objects'][i]['salinity'] salinity_unit = json_data['objects'][i]['salinity_unit'] pitch = json_data['objects'][i]['pitch'] pitch_unit = json_data['objects'][i]['pitch_unit'] roll = json_data['objects'][i]['roll'] roll_unit = json_data['objects'][i]['roll_unit'] yaw = json_data['objects'][i]['yaw'] yaw_unit = json_data['objects'][i]['yaw_unit'] altitude = json_data['objects'][i]['altitude'] altitude_unit = json_data['objects'][i]['altitude_unit'] measurement_bundle = Bundle() measurement_bundle.request = request measurement_bundle.data = dict(image='/api/dev/image/'+str(new_image.obj.id)+'/', temperature=temperature, temperature_unit=temperature_unit, salinity=salinity, salinity_unit=salinity_unit, pitch=pitch, pitch_unit=pitch_unit, roll=roll, roll_unit=roll_unit, yaw=yaw, yaw_unit=yaw_unit, altitude=altitude, altitude_unit=altitude_unit) new_measurement = MeasurementsResource().obj_create(measurement_bundle) #create camera angle = json_data['objects'][i]['angle'] name = json_data['objects'][i]['name'] camera_bundle = Bundle() camera_bundle.request = request camera_bundle.data = dict(image='/api/dev/image/'+str(new_image.obj.id)+'/', name=name, angle=int(angle)) new_camera = CameraResource().obj_create(camera_bundle) response = HttpResponse(content_type='application/json') return response return self.create_response(request, "Not all fields were provided.", response_class=HttpBadRequest)
def image_upload(self, request, **kwargs): """ Special handler function to create a project based on search criteria from images """ json_data = simplejson.loads(request.body) deployments = [] logger.debug("starting web based metadata ingest %s" % json_data["objects"][0]["deployment"]) # pull the query parameters out for i in range(0, len(json_data["objects"]), 1): deployment = json_data["objects"][i]["deployment"] deployment_id = deployment.split("/")[len(deployment.split("/")) - 2] # dp = None # if deployment_id in deployments.keys(): # dp = deployments[deployment_id] # else: # dp = Deployment.objects.filter(id=int(deployment_id)) # create the Image image_bundle = Bundle() image_bundle.request = request image_name = json_data["objects"][i]["image_name"] date_time = json_data["objects"][i]["date_time"] position = json_data["objects"][i]["position"] depth = json_data["objects"][i]["depth"] depth_uncertainty = json_data["objects"][i]["depth_uncertainty"] dpc = None if depth_uncertainty is not None and depth_uncertainty != "null": dpc = float(depth_uncertainty) image_bundle.data = dict( deployment=deployment, image_name=image_name, date_time=date_time, position=position, depth=depth, depth_uncertainty=dpc, ) new_image = self.obj_create(image_bundle) # create Measurement temperature = json_data["objects"][i]["temperature"] temperature_unit = json_data["objects"][i]["temperature_unit"] salinity = json_data["objects"][i]["salinity"] salinity_unit = json_data["objects"][i]["salinity_unit"] pitch = json_data["objects"][i]["pitch"] pitch_unit = json_data["objects"][i]["pitch_unit"] roll = json_data["objects"][i]["roll"] roll_unit = json_data["objects"][i]["roll_unit"] yaw = json_data["objects"][i]["yaw"] yaw_unit = json_data["objects"][i]["yaw_unit"] altitude = json_data["objects"][i]["altitude"] altitude_unit = json_data["objects"][i]["altitude_unit"] measurement_bundle = Bundle() measurement_bundle.request = request measurement_bundle.data = dict( image="/api/dev/image/" + str(new_image.obj.id) + "/", temperature=temperature, temperature_unit=temperature_unit, salinity=salinity, salinity_unit=salinity_unit, pitch=pitch, pitch_unit=pitch_unit, roll=roll, roll_unit=roll_unit, yaw=yaw, yaw_unit=yaw_unit, altitude=altitude, altitude_unit=altitude_unit, ) new_measurement = MeasurementsResource().obj_create(measurement_bundle) # create camera angle = json_data["objects"][i]["angle"] name = json_data["objects"][i]["name"] camera_bundle = Bundle() camera_bundle.request = request camera_bundle.data = dict( image="/api/dev/image/" + str(new_image.obj.id) + "/", name=name, angle=int(angle) ) new_camera = CameraResource().obj_create(camera_bundle) deployment_response = {"image_name": image_name, "image_uri": "/api/dev/image/" + str(new_image.obj.id)} deployments.append(deployment_response) logger.debug("finished web based metadata ingest %s" % json_data["objects"][0]["deployment"]) response = HttpResponse(content_type="application/json") response.content = json.dumps(deployments) return response return self.create_response(request, "Not all fields were provided.", response_class=HttpBadRequest)