class XFormInstanceResource(SimpleSortableResourceMixin, v0_3.XFormInstanceResource, DomainSpecificResourceMixin): # Some fields that were present when just fetching individual docs are # not present for e.g. devicelogs and must be allowed blank uiversion = fields.CharField(attribute='uiversion', blank=True, null=True) metadata = fields.DictField(attribute='metadata', blank=True, null=True) domain = fields.CharField(attribute='domain') app_id = fields.CharField(attribute='app_id', null=True) build_id = fields.CharField(attribute='build_id', null=True) cases = UseIfRequested( ToManyDocumentsField( 'corehq.apps.api.resources.v0_4.CommCareCaseResource', attribute=lambda xform: casexml_xform.cases_referenced_by_xform( xform))) is_phone_submission = fields.BooleanField(readonly=True) def dehydrate_is_phone_submission(self, bundle): return (getattr(bundle.obj, 'openrosa_headers', None) and bundle.obj.openrosa_headers.get('HTTP_X_OPENROSA_VERSION')) # Prevent hitting Couch to md5 the attachment. However, there is no way to # eliminate a tastypie field defined in a parent class. md5 = fields.CharField(attribute='uiversion', blank=True, null=True) def dehydrate_md5(self, bundle): return 'OBSOLETED' def xform_es(self, domain): return MOCK_XFORM_ES or XFormES(domain) def obj_get_list(self, bundle, domain, **kwargs): try: es_query = es_search(bundle.request, domain) except Http400 as e: raise BadRequest(e.message) es_query['filter']['and'].append( {'term': { 'doc_type': 'xforminstance' }}) # Note that XFormES is used only as an ES client, for `run_query` against the proper index return ESQuerySet( payload=es_query, model=XFormInstance, es_client=self.xform_es(domain)).order_by('-received_on') class Meta(v0_3.XFormInstanceResource.Meta): ordering = ['received_on'] list_allowed_methods = ['get']
class ToManySourceResource(Resource): other_model_ids = fields.ListField(attribute='other_model_ids') other_models = ToManyDocumentsField('corehq.apps.api.tests.ToManyDestResource', attribute='other_models') def __init__(self, objs): super(ToManySourceResource, self).__init__() self.objs = objs def obj_get_list(self): return self.objs class Meta: model_class = ToManySourceModel
class ToManySourceResource(Resource): other_model_ids = fields.ListField(attribute='other_model_ids') other_models = ToManyDocumentsField( 'corehq.apps.api.tests.core_api.ToManyDestResource', attribute='other_models') def __init__(self, objs): super(ToManySourceResource, self).__init__() self.objs = objs def obj_get_list(self): return self.objs def detail_uri_kwargs(self, bundle_or_obj): return {'pk': get_obj(bundle_or_obj).other_model_ids} class Meta(object): model_class = ToManySourceModel
class XFormInstanceResource(SimpleSortableResourceMixin, HqBaseResource, DomainSpecificResourceMixin): """This version of the form resource is built of Elasticsearch data which gets wrapped by ``ESXFormInstance``. No type conversion is done e.g. dates and some fields are named differently than in the Python models. """ id = fields.CharField(attribute='_id', readonly=True, unique=True) domain = fields.CharField(attribute='domain') form = fields.DictField(attribute='form_data') type = fields.CharField(attribute='type') version = fields.CharField(attribute='version') uiversion = fields.CharField(attribute='uiversion', blank=True, null=True) metadata = fields.DictField(attribute='metadata', blank=True, null=True) received_on = fields.CharField(attribute="received_on") app_id = fields.CharField(attribute='app_id', null=True) build_id = fields.CharField(attribute='build_id', null=True) initial_processing_complete = fields.BooleanField( attribute='initial_processing_complete', null=True) problem = fields.CharField(attribute='problem', null=True) archived = fields.CharField(readonly=True) def dehydrate_archived(self, bundle): return bundle.obj.is_archived cases = UseIfRequested( ToManyDocumentsField( 'corehq.apps.api.resources.v0_4.CommCareCaseResource', attribute=lambda xform: casexml_xform.cases_referenced_by_xform( xform))) attachments = fields.DictField(readonly=True, null=True) def dehydrate_attachments(self, bundle): attachments_dict = getattr(bundle.obj, 'blobs', None) if not attachments_dict: return {} def _normalize_meta(meta): return { 'content_type': meta.content_type, 'length': meta.content_length, } return { name: _normalize_meta(meta) for name, meta in attachments_dict.items() } is_phone_submission = fields.BooleanField(readonly=True) def dehydrate_is_phone_submission(self, bundle): return (getattr(bundle.obj, 'openrosa_headers', None) and bundle.obj.openrosa_headers.get('HTTP_X_OPENROSA_VERSION')) def obj_get(self, bundle, **kwargs): instance_id = kwargs['pk'] try: form = FormAccessors(kwargs['domain']).get_form(instance_id) es_form = form_to_es_form(form) if es_form: return es_form else: raise XFormNotFound except XFormNotFound: raise object_does_not_exist("XFormInstance", instance_id) def xform_es(self, domain): return MOCK_XFORM_ES or XFormES(domain) def obj_get_list(self, bundle, domain, **kwargs): include_archived = 'include_archived' in bundle.request.GET try: es_query = es_search(bundle.request, domain, ['include_archived']) except Http400 as e: raise BadRequest(e.message) if include_archived: es_query['filter']['and'].append({ 'or': [ { 'term': { 'doc_type': 'xforminstance' } }, { 'term': { 'doc_type': 'xformarchived' } }, ] }) else: es_query['filter']['and'].append( {'term': { 'doc_type': 'xforminstance' }}) # Note that XFormES is used only as an ES client, for `run_query` against the proper index return ElasticAPIQuerySet( payload=es_query, model=ESXFormInstance, es_client=self.xform_es(domain)).order_by('-received_on') def detail_uri_kwargs(self, bundle_or_obj): return {'pk': get_obj(bundle_or_obj).form_id} class Meta(CustomResourceMeta): authentication = RequirePermissionAuthentication(Permissions.edit_data) object_class = ESXFormInstance list_allowed_methods = ['get'] detail_allowed_methods = ['get'] resource_name = 'form' ordering = ['received_on'] serializer = XFormInstanceSerializer(formats=['json'])
class XFormInstanceResource(SimpleSortableResourceMixin, HqBaseResource, DomainSpecificResourceMixin): """This version of the form resource is built of Elasticsearch data which gets wrapped by ``ESXFormInstance``. No type conversion is done e.g. dates and some fields are named differently than in the Python models. """ id = fields.CharField(attribute='_id', readonly=True, unique=True) domain = fields.CharField(attribute='domain') form = fields.DictField(attribute='form_data') type = fields.CharField(attribute='type') version = fields.CharField(attribute='version') uiversion = fields.CharField(attribute='uiversion', blank=True, null=True) metadata = fields.DictField(attribute='metadata', blank=True, null=True) received_on = fields.CharField(attribute="received_on") edited_on = fields.CharField(attribute="edited_on", null=True) server_modified_on = fields.CharField(attribute="server_modified_on") indexed_on = fields.CharField(attribute='inserted_at') app_id = fields.CharField(attribute='app_id', null=True) build_id = fields.CharField(attribute='build_id', null=True) initial_processing_complete = fields.BooleanField( attribute='initial_processing_complete', null=True) problem = fields.CharField(attribute='problem', null=True) archived = fields.CharField(readonly=True) def dehydrate_archived(self, bundle): return bundle.obj.is_archived cases = UseIfRequested( ToManyDocumentsField( 'corehq.apps.api.resources.v0_4.CommCareCaseResource', attribute=lambda xform: _cases_referenced_by_xform(xform) ) ) attachments = fields.DictField(readonly=True, null=True) def dehydrate_attachments(self, bundle): attachments_dict = getattr(bundle.obj, 'blobs', None) if not attachments_dict: return {} domain = bundle.obj.domain form_id = bundle.obj._id def _normalize_meta(name, meta): return { 'content_type': meta.content_type, 'length': meta.content_length, 'url': absolute_reverse('api_form_attachment', args=(domain, form_id, name)) } return { name: _normalize_meta(name, meta) for name, meta in attachments_dict.items() } is_phone_submission = fields.BooleanField(readonly=True) def dehydrate_is_phone_submission(self, bundle): headers = getattr(bundle.obj, 'openrosa_headers', None) if not headers: return False return headers.get('HTTP_X_OPENROSA_VERSION') is not None edited_by_user_id = fields.CharField(readonly=True, null=True) def dehydrate_edited_by_user_id(self, bundle): if bundle.obj.edited_on: return (getattr(bundle.obj, 'auth_context') or {}).get('user_id', None) def obj_get(self, bundle, **kwargs): instance_id = kwargs['pk'] domain = kwargs['domain'] return self.xform_es(domain).get_document(instance_id) def xform_es(self, domain): return MOCK_XFORM_ES or FormESView(domain) def obj_get_list(self, bundle, domain, **kwargs): try: es_query = es_query_from_get_params(bundle.request.GET, domain, ['include_archived']) except Http400 as e: raise BadRequest(str(e)) # Note that FormESView is used only as an ES client, for `run_query` against the proper index return ElasticAPIQuerySet( payload=es_query, model=ESXFormInstance, es_client=self.xform_es(domain) ).order_by('-received_on') def detail_uri_kwargs(self, bundle_or_obj): return { 'pk': get_obj(bundle_or_obj).form_id } class Meta(CustomResourceMeta): authentication = RequirePermissionAuthentication(Permissions.edit_data) object_class = ESXFormInstance list_allowed_methods = ['get'] detail_allowed_methods = ['get'] resource_name = 'form' ordering = ['received_on', 'server_modified_on', 'indexed_on'] serializer = XFormInstanceSerializer(formats=['json'])