def _decode_class(self, class_element): """Decode a class element. Args: class_element (ElementTree): an XML element that represent a class. Returns: type. decoded class. """ type_element = getattr(class_element, TYPE_NAME) type_path = self._decode(type_element) return extract_type(type_path)
def _decode_resource_data(self, resource_element): """Decode a resource element. Args: resource_element (dict): an json element that represent a resource. Returns: BaseResource. decoded resource. """ type_element = resource_element[TYPE_NAME] type_name = self.recursive_decode(type_element) resource_type = extract_type(type_name) properties_element = resource_element[PROPERTIES] resource_properties = self.recursive_decode(properties_element) # Get the related fields. list_field_names = [ key for key, value in iteritems(resource_properties) if isinstance(value, list) ] list_fields = [(field_name, resource_properties.pop(field_name)) for field_name in list_field_names] resource = resource_type(**resource_properties) for field in resource._meta.fields: if isinstance(field, ForeignKey): if hasattr(resource, field.name): field_value = getattr(resource, field.name) if field_value: setattr(resource, "{}_id".format(field.name), field_value.id) for field_name, field_values in list_fields: # Set the related fields' values. field_object, _, is_direct, is_many_to_many = \ resource_type._meta.get_field_by_name(field_name) if is_direct: raise ParsingError("Got unsupported direct list field %r" % field_name) if is_many_to_many: raise ParsingError("Got unsupported many to many field %r" % field_name) for related_object in field_values: # Set the related model's pointer to the current model. setattr(related_object, field_object.field.name, resource) return resource
def _decode_class(self, class_element): """Decode a class element. Args: class_element (dict): an json element that represent a class. Returns: type. decoded class. """ type_element = class_element[TYPE_NAME] type_path = self._decode(type_element) return extract_type(type_path)
def _decode_resource_data(self, resource_element): """Decode a resource element. Args: resource_element (ElementTree): an XML element that represent a resource. Returns: BaseResource. decoded resource. """ type_element = getattr(resource_element, TYPE_NAME) type_name = self._decode(type_element) resource_type = extract_type(type_name) properties_element = getattr(resource_element, PROPERTIES) resource_properties = self._decode(properties_element) # Get the related fields. list_field_names = [ key for key, value in resource_properties.items() if isinstance(value, list) ] list_fields = [(field_name, resource_properties.pop(field_name)) for field_name in list_field_names] resource = resource_type(**resource_properties) for field_name, field_values in list_fields: # Set the related fields' values. field_object, _, is_direct, is_many_to_many = \ resource_type._meta.get_field_by_name(field_name) if is_direct: raise ParsingError("Got unsupported direct list field %r" % field_name) if is_many_to_many: raise ParsingError("Got unsupported many to many field %r" % field_name) for related_object in field_values: # Set the related model's pointer to the current model. setattr(related_object, field_object.field.name, resource) return resource
def _decode_resource(self, resource_element): """Decode a resource element. Args: resource_element (dict): an json element that represent a resource. Returns: BaseResource. decoded resource. """ type_element = resource_element[TYPE_NAME] type_name = self._decode(type_element) resource_type = extract_type(type_name) data_element = resource_element[DATA_NAME] resource_data = self._decode(data_element) resource = resource_type(data=resource_data) return resource
def _decode_resource(self, resource_element): """Decode a resource element. Args: resource_element (ElementTree): an XML element that represent a resource. Returns: BaseResource. decoded resource. """ type_element = getattr(resource_element, TYPE_NAME) type_name = self._decode(type_element) resource_type = extract_type(type_name) data_element = getattr(resource_element, DATA_NAME) resource_data = self._decode(data_element) resource = resource_type(data=resource_data) return resource
def put(self, request, *args, **kwargs): """Update content in the server's DB. Args: model (type): Django model to apply changes on. filter (dict): arguments to filter by. changes (dict): the additional arguments are the changes to apply on the filtered instances. """ model = extract_type(request.model.resource_descriptor.type) filter_dict = request.model.resource_descriptor.properties kwargs_vars = request.model.changes with transaction.atomic(): objects = model.objects.select_for_update() if filter_dict is not None and len(filter_dict) > 0: objects.filter(**filter_dict).update(**kwargs_vars) else: objects.all().update(**kwargs_vars) return Response({}, status=httplib.NO_CONTENT)
def decode(descriptor): """Build a ResourceDescriptor from the given dictionary. Args: descriptor (dict): a dictionary that represent a descriptor. For instance: {'type': 'my_res', 'properties': {'key1': 1}}. Returns: ResourceDescriptor. the corresponding ResourceDescriptor. Raises: ValueError: given dictionary missing a relevant key. """ for key in (TYPE_NAME, PROPERTIES): if key not in descriptor: raise ValueError("'descriptor' %r missing key %r" % (descriptor, key)) type_name = descriptor[TYPE_NAME] resource_type = extract_type(type_name) properties = descriptor[PROPERTIES] return ResourceDescriptor(resource_type, **properties)