Ejemplo n.º 1
0
def get_value_display_attr(instance, category_name, value_name, key):
    if not instance:
        raise Exception("Need an instance to format value %s.%s" % (category_name, value_name))
    # 'key' is 'units' or 'digits'
    # Make e.g. 'config.value_display.plot.width.units'
    field_name = "config.value_display.%s.%s.%s" % (category_name, value_name, key)
    # Get value from instance.config, or from defaults if not set
    value = get_attr_from_json_field(instance, field_name) or _get_display_default(category_name, value_name, key)
    identifier = "instance." + field_name
    return identifier, value
Ejemplo n.º 2
0
def get_value_display_attr(instance, category_name, value_name, key):
    if not instance:
        raise Exception("Need an instance to format value %s.%s" %
                        (category_name, value_name))
    # 'key' is 'units' or 'digits'
    # Make e.g. 'config.value_display.plot.width.units'
    field_name = 'config.value_display.%s.%s.%s' \
                 % (category_name, value_name, key)
    # Get value from instance.config, or from defaults if not set
    value = get_attr_from_json_field(instance, field_name) \
        or _get_display_default(category_name, value_name, key)
    identifier = 'instance.' + field_name
    return identifier, value
Ejemplo n.º 3
0
def _map_feature_config_validator(field_name, value, instance):
    acceptable_terms = [
        Cls.__name__ for Cls in _get_replaceable_models(instance)
    ]

    __, __, term, key = dotted_split(field_name, 4, maxsplit=3)
    field_name_valid = (term in acceptable_terms
                        and key in ('should_show_eco', 'diversion_rate'))
    if not field_name_valid:
        return [_("An invalid key was sent in the request")]

    plural = get_attr_from_json_field(instance,
                                      'config.terms.{}.plural'.format(term))

    if key == 'should_show_eco':
        if term == 'RainBarrel':
            return [
                _("Showing Ecobenefits is not applicable to {RainBarrels}").
                format(RainBarrels=plural)
            ]
    elif key == 'diversion_rate':
        if term == 'RainBarrel':
            return [
                _("The runoff coefficient is not applicable to {RainBarrels}").
                format(RainBarrels=plural)
            ]
        error_message = ("Please enter a number between 0 and 1 "
                         "for the runoff coefficient")

        if value is None or value == '':
            return [_(error_message)]

        try:
            float_value = float(value)
        except ValueError:
            return [_(error_message)]

        if not 0.0 <= float_value <= 1.0:
            return [_(error_message)]

    return None
Ejemplo n.º 4
0
def _map_feature_config_validator(field_name, value, instance):
    acceptable_terms = [
        Cls.__name__ for Cls in _get_replaceable_models(instance)]

    __, __, term, key = dotted_split(field_name, 4, maxsplit=3)
    field_name_valid = (term in acceptable_terms and
                        key in ('should_show_eco', 'diversion_rate'))
    if not field_name_valid:
        return [_("An invalid key was sent in the request")]

    plural = get_attr_from_json_field(instance, 'config.terms.{}.plural'
                                      .format(term))

    if key == 'should_show_eco':
        if term == 'RainBarrel':
            return [_("Showing Ecobenefits is not applicable to {RainBarrels}")
                    .format(RainBarrels=plural)]
    elif key == 'diversion_rate':
        if term == 'RainBarrel':
            return [_(
                "The runoff coefficient is not applicable to {RainBarrels}")
                .format(RainBarrels=plural)]
        error_message = ("Please enter a number between 0 and 1 "
                         "for the runoff coefficient")

        if value is None or value == '':
            return [_(error_message)]

        try:
            float_value = float(value)
        except ValueError:
            return [_(error_message)]

        if not 0.0 <= float_value <= 1.0:
            return [_(error_message)]

    return None
Ejemplo n.º 5
0
    def get_external_link_url(user, feature, tree=None):
        if not user or not feature or not feature.is_plot:
            return None
        instance = feature.instance
        external_link_config =  \
            get_attr_from_json_field(instance, 'config.externalLink') or None
        if not external_link_config or \
                not external_link_config.get('url', None) or \
                not external_link_config.get('text', None):
            return None
        role = Role.objects.get_role(instance, user)
        if not role.has_permission('view_external_link'):
            return None
        external_url = external_link_config['url']
        if not tree and -1 < external_url.find(r'#{tree.id}'):
            return None

        plot = feature.cast_to_subtype()
        substitutes = {
            'planting_site.id': str(plot.pk),
            'planting_site.custom_id': plot.owner_orig_id or '',
            'tree.id': tree and str(tree.pk) or ''
        }

        class UrlTemplate(Template):
            delimiter = '#'
            pattern = '''
            \#(?:
                (?P<escaped>\#)         |  # escape with repeated delimiter
                (?P<named>(?:{0}))      |  # "#foo" substitutes foo keyword
                {{(?P<braced>(?:{0}))}} |  # "#{{foo}}" substitutes foo keyword
                (?P<invalid>{{}})          # requires a name
            )
            '''.format(get_external_link_choice_pattern())

        return UrlTemplate(external_url).safe_substitute(substitutes)
Ejemplo n.º 6
0
    def get_external_link_url(user, feature, tree=None):
        if not user or not feature or not feature.is_plot:
            return None
        instance = feature.instance
        external_link_config =  \
            get_attr_from_json_field(instance, 'config.externalLink') or None
        if not external_link_config or \
                not external_link_config.get('url', None) or \
                not external_link_config.get('text', None):
            return None
        role = Role.objects.get_role(instance, user)
        if not role.has_permission('view_external_link'):
            return None
        external_url = external_link_config['url']
        if not tree and -1 < external_url.find(r'#{tree.id}'):
            return None

        plot = feature.cast_to_subtype()
        substitutes = {
            'planting_site.id': str(plot.pk),
            'planting_site.custom_id': plot.owner_orig_id or '',
            'tree.id': tree and str(tree.pk) or ''
        }

        class UrlTemplate(Template):
            delimiter = '#'
            pattern = '''
            \#(?:
                (?P<escaped>\#)         |  # escape with repeated delimiter
                (?P<named>(?:{0}))      |  # "#foo" substitutes foo keyword
                {{(?P<braced>(?:{0}))}} |  # "#{{foo}}" substitutes foo keyword
                (?P<invalid>{{}})          # requires a name
            )
            '''.format(get_external_link_choice_pattern())

        return UrlTemplate(external_url).safe_substitute(substitutes)
Ejemplo n.º 7
0
def instance_config(instance, field):
    if instance:
        return get_attr_from_json_field(instance, "config." + field)
    else:
        return None
Ejemplo n.º 8
0
 def _assert_get(self, model, field_name, value):
     val = get_attr_from_json_field(model, field_name)
     self.assertEqual(val, value)
Ejemplo n.º 9
0
 def _assert_get(self, model, field_name, value):
     val = get_attr_from_json_field(model, field_name)
     self.assertEqual(val, value)
Ejemplo n.º 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)
Ejemplo n.º 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)
Ejemplo n.º 12
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)
Ejemplo n.º 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 "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)
Ejemplo n.º 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 "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)
Ejemplo n.º 15
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)
Ejemplo n.º 16
0
def instance_config(instance, field):
    if instance:
        return get_attr_from_json_field(instance, "config." + field)
    else:
        return None
Ejemplo n.º 17
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)