示例#1
0
def _update_instance_fields(json_data, instance, validation_fn=None):
    error_dict = {}
    for identifier, value in json_data.iteritems():
        model, field_name = dotted_split(identifier, 2, maxsplit=1)

        obj = instance

        if validation_fn:
            errors = validation_fn(field_name, value, model)
            if errors is not None:
                error_dict[field_name] = errors

        if is_json_field_reference(field_name):
            set_attr_on_json_field(obj, field_name, value)
        else:
            setattr(obj, field_name, value)

    if error_dict:
        validation_error = ValidationError(error_dict)
    else:
        try:
            validate_is_public(instance)
            instance.save()
            return {'ok': True}
        except ValidationError, ve:
            validation_error = ve
示例#2
0
def _update_instance_fields(json_data, instance, validation_fn=None,
                            should_update_universal_rev=False):
    error_dict = {}
    for identifier, value in json_data.iteritems():
        model, field_name = dotted_split(identifier, 2, maxsplit=1)

        obj = instance

        if validation_fn:
            errors = validation_fn(field_name, value, model)
            if errors is not None:
                error_dict[field_name] = errors

        if is_json_field_reference(field_name):
            set_attr_on_json_field(obj, field_name, value)
        else:
            setattr(obj, field_name, value)

    if error_dict:
        validation_error = ValidationError(error_dict)
    else:
        try:
            validate_is_public(instance)
            instance.save()
            if should_update_universal_rev:
                instance.update_universal_rev()
            return {'ok': True}
        except ValidationError, ve:
            validation_error = ve
示例#3
0
def instance_info(request, instance):
    """
    Get all the info we need about a given instance

    If also includes info about the fields available for the
    instance. If a user has been specified the field info
    will be tailored to that user
    """
    user = request.user

    role = instance.default_role
    if user and not user.is_anonymous():
        instance_user = user.get_instance_user(instance)
        if instance_user:
            role = instance_user.role

    perms = {}

    for fp in role.fieldpermission_set.all():
        model = fp.model_name.lower()
        if fp.allows_reads:
            if model not in perms:
                perms[model] = []

            if is_json_field_reference(fp.field_name):
                choices = None
                data_type = "string"
            else:
                model_inst = safe_get_model_class(fp.model_name)(instance=instance)

                data_type, _, choices = field_type_label_choices(model_inst, fp.field_name, fp.display_field_name)

            digits = get_digits_if_formattable(instance, model, fp.field_name)

            units = get_units_if_convertible(instance, model, fp.field_name)

            perms[model].append(
                {
                    "data_type": data_type,
                    "choices": choices,
                    "units": units,
                    "digits": digits,
                    "can_write": fp.allows_writes,
                    "display_name": fp.display_field_name,
                    "field_name": fp.field_name,
                }
            )

    info = _instance_info_dict(instance)
    info["fields"] = perms
    info["search"] = instance.advanced_search_fields

    return info
示例#4
0
    def add_perms(field_permissions, perms):
        for fp in field_permissions:
            model = fp.model_name.lower()
            field_key = '%s.%s' % (model, fp.field_name)
            if fp.allows_reads:
                if field_key in collection_udf_dict:
                    choices = []
                    data_type = json.loads(
                        collection_udf_dict[field_key].datatype)
                elif is_json_field_reference(fp.field_name):
                    choices = None
                    data_type = "string"
                else:
                    model_inst = safe_get_model_class(fp.model_name)(
                        instance=instance)
                    data_type, __, __, choices = field_type_label_choices(
                        model_inst, fp.field_name, fp.display_field_name)

                digits = get_digits_if_formattable(
                    instance, model, fp.field_name)

                units = get_units_if_convertible(
                    instance, model, fp.field_name)

                factor = 1.0

                try:
                    factor = storage_to_instance_units_factor(
                        instance, model, fp.field_name)
                except KeyError:
                    pass

                perms[field_key] = {
                    'data_type': data_type,
                    'choices': choices,
                    'units': units,
                    'digits': digits,
                    'canonical_units_factor': 1.0 / factor,
                    'can_write': fp.allows_writes,
                    'display_name': fp.display_field_name,
                    'field_name': fp.field_name,
                    'field_key': field_key,
                    'is_collection': field_key in collection_udf_dict
                }
示例#5
0
    def add_perms(field_permissions, perms):
        for fp in field_permissions:
            model = fp.model_name.lower()
            field_key = '%s.%s' % (model, fp.field_name)
            if fp.allows_reads:
                if field_key in collection_udf_dict:
                    choices = []
                    data_type = json.loads(
                        collection_udf_dict[field_key].datatype)
                elif is_json_field_reference(fp.field_name):
                    choices = None
                    data_type = "string"
                else:
                    model_inst = safe_get_model_class(
                        fp.model_name)(instance=instance)
                    data_type, __, __, choices = field_type_label_choices(
                        model_inst, fp.field_name, fp.display_field_name)

                digits = get_digits_if_formattable(instance, model,
                                                   fp.field_name)

                units = get_units_if_convertible(instance, model,
                                                 fp.field_name)

                factor = 1.0

                try:
                    factor = storage_to_instance_units_factor(
                        instance, model, fp.field_name)
                except KeyError:
                    pass

                perms[field_key] = {
                    'data_type': data_type,
                    'choices': choices,
                    'units': units,
                    'digits': digits,
                    'canonical_units_factor': 1.0 / factor,
                    'can_write': fp.allows_writes,
                    'display_name': fp.display_field_name,
                    'field_name': fp.field_name,
                    'field_key': field_key,
                    'is_collection': field_key in collection_udf_dict
                }
示例#6
0
文件: instance.py 项目: heath/OTM2
def instance_info(request, instance):
    """
    Get all the info we need about a given instance

    If also includes info about the fields available for the
    instance. If a user has been specified the field info
    will be tailored to that user
    """
    user = request.user

    role = instance.default_role
    if user and not user.is_anonymous():
        instance_user = user.get_instance_user(instance)
        if instance_user:
            role = instance_user.role

    perms = {}

    fields_to_allow = instance.mobile_api_fields

    for fp in role.fieldpermission_set.all():
        model = fp.model_name.lower()

        if fields_to_allow and \
           fp.field_name not in fields_to_allow.get(model, []):
            continue

        if fp.allows_reads:
            if model not in perms:
                perms[model] = []

            if is_json_field_reference(fp.field_name):
                choices = None
                data_type = "string"
            else:
                model_inst = safe_get_model_class(fp.model_name)(
                    instance=instance)

                data_type, _, choices = field_type_label_choices(
                    model_inst, fp.field_name, fp.display_field_name)

            digits = get_digits_if_formattable(
                instance, model, fp.field_name)

            units = get_units_if_convertible(
                instance, model, fp.field_name)

            factor = 1.0

            try:
                factor = get_conversion_factor(
                    instance, model, fp.field_name)
            except KeyError:
                pass

            perms[model].append({
                'data_type': data_type,
                'choices': choices,
                'units': units,
                'digits': digits,
                'canonical_units_factor': 1.0 / factor,
                'can_write': fp.allows_writes,
                'display_name': fp.display_field_name,
                'field_name': fp.field_name,
                'field_key': '%s.%s' % (model, fp.field_name)
            })

    info = _instance_info_dict(instance)
    info['fields'] = perms
    info['search'] = instance.mobile_search_fields

    public_config_keys = ['scss_variables']

    info['config'] = {x: instance.config[x]
                      for x in instance.config
                      if x in public_config_keys}

    if instance.logo:
        info['logoUrl'] = instance.logo.url

    return info
示例#7
0
    def render(self, context):
        label, identifier = self.resolve_label_and_identifier(context)
        user = _resolve_variable(self.user, context)
        instance = _resolve_variable(self.instance, context)
        field_template = get_template(_resolve_variable(
                                      self.field_template, context))

        if not isinstance(identifier, basestring)\
           or not _identifier_regex.match(identifier):
            raise template.TemplateSyntaxError(
                'expected a string with the format "model.property" '
                'to follow "from" %s' % identifier)

        model_name, field_name = identifier.split('.', 1)
        model = self.get_model(context, model_name, instance)

        def _is_udf(model, udf_field_name):
            return (hasattr(model, 'udf_field_names') and
                    udf_field_name in model.udf_field_names)

        def _udf_dict(model, field_name):
            return model.get_user_defined_fields()\
                .filter(name=field_name.replace('udf:', ''))[0]\
                .datatype_dict

        def _field_type_label_choices(model, field_name, label):
            choices = None
            udf_field_name = field_name.replace('udf:', '')
            if not _is_udf(model, udf_field_name):
                field = model._meta.get_field(field_name)
                field_type = field.get_internal_type()
                try:
                    field_type = FieldNode._field_mappings[field_type]
                except KeyError:
                    raise Exception('This template tag only supports %s not %s'
                                    % (FieldNode._valid_field_keys,
                                       field_type))
                label = label if label else field.help_text
                choices = [{'value': choice[0], 'display_value': choice[1]}
                           for choice in field.choices]
                if choices and field.null:
                    choices = [{'value': '', 'display_value': ''}] + choices
            else:
                udf_dict = _udf_dict(model, field_name)
                field_type = udf_dict['type']
                label = label if label else udf_field_name
                if 'choices' in udf_dict:
                    values = [''] + udf_dict['choices']
                    choices = [{'value': value, 'display_value': value}
                               for value in values]

            return field_type, label, choices

        def _field_value(model, field_name):
            udf_field_name = field_name.replace('udf:', '')
            if field_name in model._meta.get_all_field_names():
                try:
                    val = getattr(model, field_name)
                except ObjectDoesNotExist:
                    val = None
            elif _is_udf(model, udf_field_name):
                val = model.udfs[udf_field_name]
            else:
                raise ValueError('Could not find field: %s' % field_name)

            return val

        if is_json_field_reference(field_name):
            field_value = get_attr_from_json_field(model, field_name)
            choices = None
            is_visible = is_editable = True
            data_type = "string"
        else:
            field_value = _field_value(model, field_name)
            data_type, label, choices = _field_type_label_choices(
                model, field_name, label)

            if user is not None and hasattr(model, 'field_is_visible'):
                is_visible = model.field_is_visible(user, field_name)
                is_editable = model.field_is_editable(user, field_name)
            else:
                # This tag can be used without specifying a user. In that case
                # we assume that the content is visible and upstream code is
                # responsible for only showing the content to the appropriate
                # user
                is_visible = True
                is_editable = True

        digits = (get_digits(model.instance, model_name, field_name)
                  if is_formattable(model_name, field_name) else '')

        units = ''
        if is_convertible(model_name, field_name):
            units = get_units(model.instance, model_name, field_name)

        if field_value is None:
            display_val = None
        elif data_type == 'date' and model.instance:
            display_val = dateformat.format(field_value,
                                            model.instance.short_date_format)
        elif data_type == 'date':
            display_val = dateformat.format(field_value,
                                            settings.SHORT_DATE_FORMAT)
        elif is_convertible_or_formattable(model_name, field_name):
            field_value, display_val = get_display_value(
                model.instance, model_name, field_name, field_value)
            if units is not '':
                display_val += (' %s' % units)
        else:
            display_val = unicode(field_value)

        context['field'] = {
            'label': label,
            'identifier': identifier,
            'value': field_value,
            'display_value': display_val,
            'units': units,
            'digits': digits,
            'data_type': data_type,
            'is_visible': is_visible,
            'is_editable': is_editable,
            'choices': choices
        }
        self.get_additional_context(context['field'])

        return field_template.render(context)
示例#8
0
def instance_info(request, instance):
    """
    Get all the info we need about a given instance

    It also includes info about the fields available for the
    instance. If a user has been specified the field info
    will be tailored to that user
    """
    user = request.user

    role = instance.default_role
    if user and not user.is_anonymous():
        instance_user = user.get_instance_user(instance)
        if instance_user:
            role = instance_user.role

    collection_udfs = instance.userdefinedfielddefinition_set\
                              .filter(iscollection=True)
    collection_udf_dict = {
        "%s.%s" % (udf.model_type.lower(), udf.canonical_name): udf
        for udf in collection_udfs
    }

    # collect perms for the given role/instance into a serializable
    # dictionary. If a field isn't at least readable, it doesn't
    # get sent over at all.
    perms = {}
    for fp in role_permissions(role, instance):
        model = fp.model_name.lower()
        field_key = '%s.%s' % (model, fp.field_name)
        if fp.allows_reads:
            if field_key in collection_udf_dict:
                choices = []
                data_type = json.loads(collection_udf_dict[field_key].datatype)
            elif is_json_field_reference(fp.field_name):
                choices = None
                data_type = "string"
            else:
                model_inst = safe_get_model_class(
                    fp.model_name)(instance=instance)
                data_type, __, choices = field_type_label_choices(
                    model_inst, fp.field_name, fp.display_field_name)

            digits = get_digits_if_formattable(instance, model, fp.field_name)

            units = get_units_if_convertible(instance, model, fp.field_name)

            factor = 1.0

            try:
                factor = get_conversion_factor(instance, model, fp.field_name)
            except KeyError:
                pass

            perms[field_key] = {
                'data_type': data_type,
                'choices': choices,
                'units': units,
                'digits': digits,
                'canonical_units_factor': 1.0 / factor,
                'can_write': fp.allows_writes,
                'display_name': fp.display_field_name,
                'field_name': fp.field_name,
                'field_key': field_key,
                'is_collection': field_key in collection_udf_dict
            }

    def get_key_for_group(field_group):
        for key in ('collection_udf_keys', 'field_keys'):
            if key in field_group:
                return key
        return None

    # Remove fields from mobile_api_fields if they are not present in perms
    # (Generally because the user doesn't have read permissions)
    # If no fields are left in a group, remove the group
    mobile_api_fields = copy.deepcopy(instance.mobile_api_fields)

    for field_group in mobile_api_fields:
        # Field group headers are stored in English, and translated when they
        # are sent out to the client
        field_group['header'] = _(field_group['header'])
        key = get_key_for_group(field_group)
        if key:
            field_group[key] = [
                field for field in field_group[key] if field in perms
            ]

    readable_mobile_api_fields = [
        group for group in mobile_api_fields
        if group.get(get_key_for_group(group), None)
    ]

    info = _instance_info_dict(instance)
    info['fields'] = perms
    info['field_key_groups'] = readable_mobile_api_fields
    info['search'] = instance.mobile_search_fields
    info['date_format'] = _unicode_dateformat(instance.date_format)
    info['short_date_format'] = _unicode_dateformat(instance.short_date_format)

    info['meta_perms'] = {
        'can_add_tree': perms_lib.plot_is_creatable(role),
        'can_edit_tree': perms_lib.plot_is_writable(role),
        'can_edit_tree_photo': perms_lib.treephoto_is_writable(role),
    }

    public_config_keys = ['scss_variables']

    info['config'] = {
        x: instance.config[x]
        for x in instance.config if x in public_config_keys
    }

    if instance.logo:
        info['logoUrl'] = instance.logo.url

    return info
示例#9
0
def instance_info(request, instance):
    """
    Get all the info we need about a given instance

    It also includes info about the fields available for the
    instance. If a user has been specified the field info
    will be tailored to that user
    """
    user = request.user

    role = instance.default_role
    if user and not user.is_anonymous():
        instance_user = user.get_instance_user(instance)
        if instance_user:
            role = instance_user.role

    collection_udfs = instance.collection_udfs
    collection_udf_dict = {"%s.%s" % (udf.model_type.lower(),
                                      udf.canonical_name): udf
                           for udf in collection_udfs}

    # collect perms for the given role/instance into a serializable
    # dictionary. If a field isn't at least readable, it doesn't
    # get sent over at all.
    perms = {}
    for fp in role_permissions(role, instance):
        model = fp.model_name.lower()
        field_key = '%s.%s' % (model, fp.field_name)
        if fp.allows_reads:
            if field_key in collection_udf_dict:
                choices = []
                data_type = json.loads(collection_udf_dict[field_key].datatype)
            elif is_json_field_reference(fp.field_name):
                choices = None
                data_type = "string"
            else:
                model_inst = safe_get_model_class(fp.model_name)(
                    instance=instance)
                data_type, __, choices = field_type_label_choices(
                    model_inst, fp.field_name, fp.display_field_name)

            digits = get_digits_if_formattable(
                instance, model, fp.field_name)

            units = get_units_if_convertible(
                instance, model, fp.field_name)

            factor = 1.0

            try:
                factor = storage_to_instance_units_factor(
                    instance, model, fp.field_name)
            except KeyError:
                pass

            perms[field_key] = {
                'data_type': data_type,
                'choices': choices,
                'units': units,
                'digits': digits,
                'canonical_units_factor': 1.0 / factor,
                'can_write': fp.allows_writes,
                'display_name': fp.display_field_name,
                'field_name': fp.field_name,
                'field_key': field_key,
                'is_collection': field_key in collection_udf_dict
            }

    def get_key_for_group(field_group):
        for key in ('collection_udf_keys', 'field_keys'):
            if key in field_group:
                return key
        return None

    # Remove fields from mobile_api_fields if they are not present in perms
    # (Generally because the user doesn't have read permissions)
    # If no fields are left in a group, remove the group
    mobile_api_fields = copy.deepcopy(instance.mobile_api_fields)

    for field_group in mobile_api_fields:
        # Field group headers are stored in English, and translated when they
        # are sent out to the client
        field_group['header'] = _(field_group['header'])
        key = get_key_for_group(field_group)
        if key:
            field_group[key] = [field for field in field_group[key]
                                if field in perms]

    readable_mobile_api_fields = [group for group in mobile_api_fields
                                  if group.get(get_key_for_group(group), None)]

    info = _instance_info_dict(instance)
    info['fields'] = perms
    info['field_key_groups'] = readable_mobile_api_fields
    info['search'] = mobile_search_fields(instance)
    info['date_format'] = _unicode_dateformat(instance.date_format)
    info['short_date_format'] = _unicode_dateformat(instance.short_date_format)

    info['meta_perms'] = {
        'can_add_tree': perms_lib.plot_is_creatable(role),
        'can_edit_tree': perms_lib.plot_is_writable(role),
        'can_edit_tree_photo': perms_lib.treephoto_is_writable(role),
    }

    public_config_keys = ['scss_variables']

    info['config'] = {x: instance.config[x]
                      for x in instance.config
                      if x in public_config_keys}

    if instance.logo:
        info['logoUrl'] = instance.logo.url

    return info
示例#10
0
    def render(self, context):
        explanation = _resolve_variable(self.explanation, context)
        label, identifier = self.resolve_label_and_identifier(context)
        user = _resolve_variable(self.user, context)
        instance = _resolve_variable(self.instance, context)
        field_template = get_template(_resolve_variable(
                                      self.field_template, context)).template

        if not isinstance(identifier, basestring)\
           or not _identifier_regex.match(identifier):
            raise template.TemplateSyntaxError(
                'expected a string with the format "object_name.property" '
                'to follow "from" %s' % identifier)

        model_name_or_object_name, field_name = dotted_split(identifier, 2,
                                                             maxsplit=1)
        model = self.get_model(context, model_name_or_object_name, instance)

        object_name = to_object_name(model_name_or_object_name)

        identifier = "%s.%s" % (object_name, field_name)

        def _field_value(model, field_name, data_type):
            udf_field_name = field_name.replace('udf:', '')
            val = None
            if field_name in [f.name for f in model._meta.get_fields()]:
                try:
                    val = getattr(model, field_name)
                except (ObjectDoesNotExist, AttributeError):
                    pass
            elif _is_udf(model, udf_field_name):
                if udf_field_name in model.udfs:
                    val = model.udfs[udf_field_name]
                    # multichoices place a json serialized data-value
                    # on the dom element and client-side javascript
                    # processes it into a view table and edit widget
                    if data_type == 'multichoice':
                        val = json.dumps(val)
                elif data_type == 'multichoice':
                    val = '[]'
            else:
                raise ValueError('Could not find field: %s' % field_name)

            return val

        if is_json_field_reference(field_name):
            field_value = get_attr_from_json_field(model, field_name)
            choices = None
            is_visible = is_editable = True
            data_type = "string"
        else:
            add_blank = (ADD_BLANK_ALWAYS if self.treat_multichoice_as_choice
                         else ADD_BLANK_IF_CHOICE_FIELD)
            data_type, label, explanation, choices = field_type_label_choices(
                model, field_name, label, explanation=explanation,
                add_blank=add_blank)
            field_value = _field_value(model, field_name, data_type)

            if user is not None and hasattr(model, 'field_is_visible'):
                is_visible = model.field_is_visible(user, field_name)
                is_editable = model.field_is_editable(user, field_name)
            else:
                # This tag can be used without specifying a user. In that case
                # we assume that the content is visible and upstream code is
                # responsible for only showing the content to the appropriate
                # user
                is_visible = True
                is_editable = True

        digits = units = ''

        if hasattr(model, 'instance'):
            digits = get_digits_if_formattable(
                model.instance, object_name, field_name)

            units = get_units_if_convertible(
                model.instance, object_name, field_name)
            if units != '':
                units = get_unit_abbreviation(units)

        if data_type == 'foreign_key':
            # rendered clientside
            display_val = ''
        elif field_value is None:
            display_val = None
        elif data_type in ['date', 'datetime']:
            fmt = (model.instance.short_date_format if model.instance
                   else settings.SHORT_DATE_FORMAT)
            display_val = dateformat.format(field_value, fmt)
        elif is_convertible_or_formattable(object_name, field_name):
            display_val = format_value(
                model.instance, object_name, field_name, field_value)
            if units != '':
                display_val += (' %s' % units)
        elif data_type == 'bool':
            display_val = _('Yes') if field_value else _('No')
        elif data_type == 'multichoice':
            # this is rendered clientside from data attributes so
            # there's no meaningful intermediate value to send
            # without rendering the same markup server-side.
            display_val = None
        elif choices:
            display_vals = [choice['display_value'] for choice in choices
                            if choice['value'] == field_value]
            display_val = display_vals[0] if display_vals else field_value
        else:
            display_val = unicode(field_value)

        context['field'] = {
            'label': label,
            'explanation': explanation,
            'identifier': identifier,
            'value': field_value,
            'display_value': display_val,
            'units': units,
            'digits': digits,
            'data_type': data_type,
            'is_visible': is_visible,
            'is_editable': is_editable,
            'choices': choices,
        }
        self.get_additional_context(
            context['field'], model, field_name, context.get('q', ''))

        return field_template.render(context)
示例#11
0
    def render(self, context):
        label, identifier = self.resolve_label_and_identifier(context)
        user = _resolve_variable(self.user, context)
        instance = _resolve_variable(self.instance, context)
        field_template = get_template(_resolve_variable(self.field_template, context))

        if not isinstance(identifier, basestring) or not _identifier_regex.match(identifier):
            raise template.TemplateSyntaxError(
                'expected a string with the format "object_name.property" ' 'to follow "from" %s' % identifier
            )

        model_name_or_object_name, field_name = identifier.split(".", 1)
        model = self.get_model(context, model_name_or_object_name, instance)

        object_name = to_object_name(model_name_or_object_name)
        identifier = "%s.%s" % (object_name, field_name)

        def _field_value(model, field_name):
            udf_field_name = field_name.replace("udf:", "")
            if field_name in model._meta.get_all_field_names():
                try:
                    val = getattr(model, field_name)
                except ObjectDoesNotExist:
                    val = None
            elif _is_udf(model, udf_field_name):
                val = model.udfs[udf_field_name]
            else:
                raise ValueError("Could not find field: %s" % field_name)

            return val

        if is_json_field_reference(field_name):
            field_value = get_attr_from_json_field(model, field_name)
            choices = None
            is_visible = is_editable = True
            data_type = "string"
        else:
            field_value = _field_value(model, field_name)
            data_type, label, choices = field_type_label_choices(model, field_name, label)

            if user is not None and hasattr(model, "field_is_visible"):
                is_visible = model.field_is_visible(user, field_name)
                is_editable = model.field_is_editable(user, field_name)
            else:
                # This tag can be used without specifying a user. In that case
                # we assume that the content is visible and upstream code is
                # responsible for only showing the content to the appropriate
                # user
                is_visible = True
                is_editable = True

        digits = units = ""

        if hasattr(model, "instance"):
            digits = get_digits_if_formattable(model.instance, object_name, field_name)

            units = get_units_if_convertible(model.instance, object_name, field_name)

        if field_value is None:
            display_val = None
        elif data_type == "date" and model.instance:
            display_val = dateformat.format(field_value, model.instance.short_date_format)
        elif data_type == "date":
            display_val = dateformat.format(field_value, settings.SHORT_DATE_FORMAT)
        elif is_convertible_or_formattable(object_name, field_name):
            display_val = format_value(model.instance, object_name, field_name, field_value)
            if units != "":
                display_val += " %s" % units
        elif data_type == "bool":
            display_val = trans("Yes") if field_value else trans("No")
        else:
            display_val = unicode(field_value)

        context["field"] = {
            "label": label,
            "identifier": identifier,
            "value": field_value,
            "display_value": display_val,
            "units": units,
            "digits": digits,
            "data_type": data_type,
            "is_visible": is_visible,
            "is_editable": is_editable,
            "choices": choices,
        }
        self.get_additional_context(context["field"])

        return field_template.render(context)
示例#12
0
    def render(self, context):
        explanation = _resolve_variable(self.explanation, context)
        label, identifier = self.resolve_label_and_identifier(context)
        user = _resolve_variable(self.user, context)
        instance = _resolve_variable(self.instance, context)
        field_template = get_template(_resolve_variable(
                                      self.field_template, context)).template

        if not isinstance(identifier, basestring)\
           or not _identifier_regex.match(identifier):
            raise template.TemplateSyntaxError(
                'expected a string with the format "object_name.property" '
                'to follow "from" %s' % identifier)

        model_name_or_object_name, field_name = dotted_split(identifier, 2,
                                                             maxsplit=1)
        model = self.get_model(context, model_name_or_object_name, instance)

        object_name = to_object_name(model_name_or_object_name)

        identifier = "%s.%s" % (object_name, field_name)

        def _field_value(model, field_name, data_type):
            udf_field_name = field_name.replace('udf:', '')
            val = None
            if field_name in [f.name for f in model._meta.get_fields()]:
                try:
                    val = getattr(model, field_name)
                except (ObjectDoesNotExist, AttributeError):
                    pass
            elif _is_udf(model, udf_field_name):
                if udf_field_name in model.udfs:
                    val = model.udfs[udf_field_name]
                    # multichoices place a json serialized data-value
                    # on the dom element and client-side javascript
                    # processes it into a view table and edit widget
                    if data_type == 'multichoice':
                        val = json.dumps(val)
                elif data_type == 'multichoice':
                    val = '[]'
            else:
                raise ValueError('Could not find field: %s' % field_name)

            return val

        if is_json_field_reference(field_name):
            field_value = get_attr_from_json_field(model, field_name)
            choices = None
            is_visible = is_editable = True
            data_type = "string"
        else:
            add_blank = (ADD_BLANK_ALWAYS if self.treat_multichoice_as_choice
                         else ADD_BLANK_IF_CHOICE_FIELD)
            data_type, label, explanation, choices = field_type_label_choices(
                model, field_name, label, explanation=explanation,
                add_blank=add_blank)
            field_value = _field_value(model, field_name, data_type)

            if user is not None and hasattr(model, 'field_is_visible'):
                is_visible = model.field_is_visible(user, field_name)
                is_editable = model.field_is_editable(user, field_name)
            else:
                # This tag can be used without specifying a user. In that case
                # we assume that the content is visible and upstream code is
                # responsible for only showing the content to the appropriate
                # user
                is_visible = True
                is_editable = True

        digits = units = ''

        if hasattr(model, 'instance'):
            digits = get_digits_if_formattable(
                model.instance, object_name, field_name)

            units = get_units_if_convertible(
                model.instance, object_name, field_name)
            if units != '':
                units = get_unit_abbreviation(units)

        if data_type == 'foreign_key':
            # rendered clientside
            display_val = ''
        elif field_value is None:
            display_val = None
        elif data_type in ['date', 'datetime']:
            fmt = (model.instance.short_date_format if model.instance
                   else settings.SHORT_DATE_FORMAT)
            display_val = dateformat.format(field_value, fmt)
        elif is_convertible_or_formattable(object_name, field_name):
            display_val = format_value(
                model.instance, object_name, field_name, field_value)
            if units != '':
                display_val += (' %s' % units)
        elif data_type == 'bool':
            display_val = _('Yes') if field_value else _('No')
        elif data_type == 'multichoice':
            # this is rendered clientside from data attributes so
            # there's no meaningful intermediate value to send
            # without rendering the same markup server-side.
            display_val = None
        elif choices:
            display_vals = [choice['display_value'] for choice in choices
                            if choice['value'] == field_value]
            display_val = display_vals[0] if display_vals else field_value
        elif data_type == 'float':
            display_val = num_format(field_value)
        else:
            display_val = unicode(field_value)

        context['field'] = {
            'label': label,
            'explanation': explanation,
            'identifier': identifier,
            'value': field_value,
            'display_value': display_val,
            'units': units,
            'digits': digits,
            'data_type': data_type,
            'is_visible': is_visible,
            'is_editable': is_editable,
            'choices': choices,
        }
        self.get_additional_context(
            context['field'], model, field_name, context.get('q', ''))

        return field_template.render(context)
示例#13
0
    def render(self, context):
        label, identifier = self.resolve_label_and_identifier(context)
        user = _resolve_variable(self.user, context)
        instance = _resolve_variable(self.instance, context)
        field_template = get_template(_resolve_variable(
                                      self.field_template, context))

        if not isinstance(identifier, basestring)\
           or not _identifier_regex.match(identifier):
            raise template.TemplateSyntaxError(
                'expected a string with the format "object_name.property" '
                'to follow "from" %s' % identifier)

        model_name_or_object_name, field_name = dotted_split(identifier, 2,
                                                             maxsplit=1)
        model = self.get_model(context, model_name_or_object_name, instance)

        object_name = to_object_name(model_name_or_object_name)
        identifier = "%s.%s" % (object_name, field_name)

        def _field_value(model, field_name, data_type):
            udf_field_name = field_name.replace('udf:', '')
            if field_name in model._meta.get_all_field_names():
                try:
                    val = getattr(model, field_name)
                except ObjectDoesNotExist:
                    val = None
            elif _is_udf(model, udf_field_name):
                val = model.udfs[udf_field_name]
                # multichoices place a json serialized data-value
                # on the dom element and client-side javascript
                # processes it into a view table and edit widget
                if data_type == 'multichoice':
                    val = json.dumps(val)
            else:
                raise ValueError('Could not find field: %s' % field_name)

            return val

        if is_json_field_reference(field_name):
            field_value = get_attr_from_json_field(model, field_name)
            choices = None
            is_visible = is_editable = True
            data_type = "string"
        else:
            data_type, label, choices = field_type_label_choices(
                model, field_name, label)
            field_value = _field_value(model, field_name, data_type)

            if user is not None and hasattr(model, 'field_is_visible'):
                is_visible = model.field_is_visible(user, field_name)
                is_editable = model.field_is_editable(user, field_name)
            else:
                # This tag can be used without specifying a user. In that case
                # we assume that the content is visible and upstream code is
                # responsible for only showing the content to the appropriate
                # user
                is_visible = True
                is_editable = True

        digits = units = ''

        if hasattr(model, 'instance'):
            digits = get_digits_if_formattable(
                model.instance, object_name, field_name)

            units = get_units_if_convertible(
                model.instance, object_name, field_name)

        if field_value is None:
            display_val = None
        elif data_type == 'date' and model.instance:
            display_val = dateformat.format(field_value,
                                            model.instance.short_date_format)
        elif data_type == 'date':
            display_val = dateformat.format(field_value,
                                            settings.SHORT_DATE_FORMAT)
        elif is_convertible_or_formattable(object_name, field_name):
            display_val = format_value(
                model.instance, object_name, field_name, field_value)
            if units != '':
                display_val += (' %s' % units)
        elif data_type == 'bool':
            display_val = _('Yes') if field_value else _('No')
        elif data_type == 'multichoice':
            # this is rendered clientside from data attributes so
            # there's no meaningful intermediate value to send
            # without rendering the same markup server-side.
            display_val = None
        else:
            display_val = unicode(field_value)

        context['field'] = {
            'label': label,
            'identifier': identifier,
            'value': field_value,
            'display_value': display_val,
            'units': units,
            'digits': digits,
            'data_type': data_type,
            'is_visible': is_visible,
            'is_editable': is_editable,
            'choices': choices
        }
        self.get_additional_context(context['field'])

        return field_template.render(context)
示例#14
0
    def render(self, context):
        label, identifier = self.resolve_label_and_identifier(context)
        user = _resolve_variable(self.user, context)
        instance = _resolve_variable(self.instance, context)
        field_template = get_template(_resolve_variable(
                                      self.field_template, context))

        if not isinstance(identifier, basestring)\
           or not _identifier_regex.match(identifier):
            raise template.TemplateSyntaxError(
                'expected a string with the format "model.property" '
                'to follow "from" %s' % identifier)

        model_name, field_name = identifier.split('.', 1)
        model = self.get_model(context, model_name, instance)

        def _field_value(model, field_name):
            udf_field_name = field_name.replace('udf:', '')
            if field_name in model._meta.get_all_field_names():
                try:
                    val = getattr(model, field_name)
                except ObjectDoesNotExist:
                    val = None
            elif _is_udf(model, udf_field_name):
                val = model.udfs[udf_field_name]
            else:
                raise ValueError('Could not find field: %s' % field_name)

            return val

        if is_json_field_reference(field_name):
            field_value = get_attr_from_json_field(model, field_name)
            choices = None
            is_visible = is_editable = True
            data_type = "string"
        else:
            field_value = _field_value(model, field_name)
            data_type, label, choices = field_type_label_choices(
                model, field_name, label)

            if user is not None and hasattr(model, 'field_is_visible'):
                is_visible = model.field_is_visible(user, field_name)
                is_editable = model.field_is_editable(user, field_name)
            else:
                # This tag can be used without specifying a user. In that case
                # we assume that the content is visible and upstream code is
                # responsible for only showing the content to the appropriate
                # user
                is_visible = True
                is_editable = True

        digits = units = ''

        if hasattr(model, 'instance'):
            digits = get_digits_if_formattable(
                model.instance, model_name, field_name)

            units = get_units_if_convertible(
                model.instance, model_name, field_name)

        if field_value is None:
            display_val = None
        elif data_type == 'date' and model.instance:
            display_val = dateformat.format(field_value,
                                            model.instance.short_date_format)
        elif data_type == 'date':
            display_val = dateformat.format(field_value,
                                            settings.SHORT_DATE_FORMAT)
        elif is_convertible_or_formattable(model_name, field_name):
            field_value, display_val = get_display_value(
                model.instance, model_name, field_name, field_value)
            if units is not '':
                display_val += (' %s' % units)
        else:
            display_val = unicode(field_value)

        context['field'] = {
            'label': label,
            'identifier': identifier,
            'value': field_value,
            'display_value': display_val,
            'units': units,
            'digits': digits,
            'data_type': data_type,
            'is_visible': is_visible,
            'is_editable': is_editable,
            'choices': choices
        }
        self.get_additional_context(context['field'])

        return field_template.render(context)
示例#15
0
def instance_info(request, instance):
    """
    Get all the info we need about a given instance

    If also includes info about the fields available for the
    instance. If a user has been specified the field info
    will be tailored to that user
    """
    user = request.user

    role = instance.default_role
    if user and not user.is_anonymous():
        instance_user = user.get_instance_user(instance)
        if instance_user:
            role = instance_user.role

    perms = {}

    collection_udfs = instance.userdefinedfielddefinition_set\
                              .filter(iscollection=True)
    collection_udf_dict = {
        "%s.%s" % (udf.model_type.lower(), udf.canonical_name): udf
        for udf in collection_udfs
    }

    for fp in role.fieldpermission_set.all():
        model = fp.model_name.lower()
        field_key = '%s.%s' % (model, fp.field_name)
        if fp.allows_reads:
            if field_key in collection_udf_dict:
                choices = []
                data_type = collection_udf_dict[field_key].datatype
            elif is_json_field_reference(fp.field_name):
                choices = None
                data_type = "string"
            else:
                model_inst = safe_get_model_class(
                    fp.model_name)(instance=instance)
                data_type, _, choices = field_type_label_choices(
                    model_inst, fp.field_name, fp.display_field_name)

            digits = get_digits_if_formattable(instance, model, fp.field_name)

            units = get_units_if_convertible(instance, model, fp.field_name)

            factor = 1.0

            try:
                factor = get_conversion_factor(instance, model, fp.field_name)
            except KeyError:
                pass

            perms[field_key] = {
                'data_type': data_type,
                'choices': choices,
                'units': units,
                'digits': digits,
                'canonical_units_factor': 1.0 / factor,
                'can_write': fp.allows_writes,
                'display_name': fp.display_field_name,
                'field_name': fp.field_name,
                'field_key': field_key,
                'is_collection': field_key in collection_udf_dict
            }

    info = _instance_info_dict(instance)
    info['fields'] = perms
    info['field_key_groups'] = instance.mobile_api_fields
    info['search'] = instance.mobile_search_fields

    public_config_keys = ['scss_variables']

    info['config'] = {
        x: instance.config[x]
        for x in instance.config if x in public_config_keys
    }

    if instance.logo:
        info['logoUrl'] = instance.logo.url

    return info
示例#16
0
文件: form_extras.py 项目: gapb/OTM2
    def render(self, context):
        label, identifier = self.resolve_label_and_identifier(context)
        user = _resolve_variable(self.user, context)
        instance = _resolve_variable(self.instance, context)
        field_template = get_template(_resolve_variable(
                                      self.field_template, context))

        if not isinstance(identifier, basestring)\
           or not _identifier_regex.match(identifier):
            raise template.TemplateSyntaxError(
                'expected a string with the format "object_name.property" '
                'to follow "from" %s' % identifier)

        model_name_or_object_name, field_name = dotted_split(identifier, 2,
                                                             maxsplit=1)
        model = self.get_model(context, model_name_or_object_name, instance)

        object_name = to_object_name(model_name_or_object_name)
        identifier = "%s.%s" % (object_name, field_name)

        def _field_value(model, field_name):
            udf_field_name = field_name.replace('udf:', '')
            if field_name in model._meta.get_all_field_names():
                try:
                    val = getattr(model, field_name)
                except ObjectDoesNotExist:
                    val = None
            elif _is_udf(model, udf_field_name):
                val = model.udfs[udf_field_name]
            else:
                raise ValueError('Could not find field: %s' % field_name)

            return val

        if is_json_field_reference(field_name):
            field_value = get_attr_from_json_field(model, field_name)
            choices = None
            is_visible = is_editable = True
            data_type = "string"
        else:
            field_value = _field_value(model, field_name)
            data_type, label, choices = field_type_label_choices(
                model, field_name, label)

            if user is not None and hasattr(model, 'field_is_visible'):
                is_visible = model.field_is_visible(user, field_name)
                is_editable = model.field_is_editable(user, field_name)
            else:
                # This tag can be used without specifying a user. In that case
                # we assume that the content is visible and upstream code is
                # responsible for only showing the content to the appropriate
                # user
                is_visible = True
                is_editable = True

        digits = units = ''

        if hasattr(model, 'instance'):
            digits = get_digits_if_formattable(
                model.instance, object_name, field_name)

            units = get_units_if_convertible(
                model.instance, object_name, field_name)

        if field_value is None:
            display_val = None
        elif data_type == 'date' and model.instance:
            display_val = dateformat.format(field_value,
                                            model.instance.short_date_format)
        elif data_type == 'date':
            display_val = dateformat.format(field_value,
                                            settings.SHORT_DATE_FORMAT)
        elif is_convertible_or_formattable(object_name, field_name):
            display_val = format_value(
                model.instance, object_name, field_name, field_value)
            if units != '':
                display_val += (' %s' % units)
        elif data_type == 'bool':
            display_val = trans('Yes') if field_value else trans('No')
        else:
            display_val = unicode(field_value)

        context['field'] = {
            'label': label,
            'identifier': identifier,
            'value': field_value,
            'display_value': display_val,
            'units': units,
            'digits': digits,
            'data_type': data_type,
            'is_visible': is_visible,
            'is_editable': is_editable,
            'choices': choices
        }
        self.get_additional_context(context['field'])

        return field_template.render(context)
示例#17
0
文件: instance.py 项目: dandye/OTM2
def instance_info(request, instance):
    """
    Get all the info we need about a given instance

    It also includes info about the fields available for the
    instance. If a user has been specified the field info
    will be tailored to that user
    """
    user = request.user

    role = instance.default_role
    if user and not user.is_anonymous():
        instance_user = user.get_instance_user(instance)
        if instance_user:
            role = instance_user.role

    collection_udfs = instance.userdefinedfielddefinition_set\
                              .filter(iscollection=True)
    collection_udf_dict = {"%s.%s" % (udf.model_type.lower(),
                                      udf.canonical_name): udf
                           for udf in collection_udfs}

    # collect perms for the given role/instance into a serializable
    # dictionary. If a field isn't at least readable, it doesn't
    # get sent over at all.
    perms = {}
    for fp in role_permissions(role, instance):
        model = fp.model_name.lower()
        field_key = '%s.%s' % (model, fp.field_name)
        if fp.allows_reads:
            if field_key in collection_udf_dict:
                choices = []
                data_type = collection_udf_dict[field_key].datatype
            elif is_json_field_reference(fp.field_name):
                choices = None
                data_type = "string"
            else:
                model_inst = safe_get_model_class(fp.model_name)(
                    instance=instance)
                data_type, _, choices = field_type_label_choices(
                    model_inst, fp.field_name, fp.display_field_name)

            digits = get_digits_if_formattable(
                instance, model, fp.field_name)

            units = get_units_if_convertible(
                instance, model, fp.field_name)

            factor = 1.0

            try:
                factor = get_conversion_factor(
                    instance, model, fp.field_name)
            except KeyError:
                pass

            perms[field_key] = {
                'data_type': data_type,
                'choices': choices,
                'units': units,
                'digits': digits,
                'canonical_units_factor': 1.0 / factor,
                'can_write': fp.allows_writes,
                'display_name': fp.display_field_name,
                'field_name': fp.field_name,
                'field_key': field_key,
                'is_collection': field_key in collection_udf_dict
            }

    info = _instance_info_dict(instance)
    info['fields'] = perms
    info['field_key_groups'] = instance.mobile_api_fields
    info['search'] = instance.mobile_search_fields
    info['date_format'] = _unicode_dateformat(instance.date_format)
    info['short_date_format'] = _unicode_dateformat(instance.short_date_format)

    info['meta_perms'] = {
        'can_add_tree': perms_lib.plot_is_creatable(role),
        'can_edit_tree': perms_lib.plot_is_writable(role),
        'can_edit_tree_photo': perms_lib.treephoto_is_writable(role),
    }

    public_config_keys = ['scss_variables']

    info['config'] = {x: instance.config[x]
                      for x in instance.config
                      if x in public_config_keys}

    if instance.logo:
        info['logoUrl'] = instance.logo.url

    return info