Example #1
0
 def choice(**kwargs):
     choices = kwargs["choices"]
     setdefaults(
         kwargs,
         dict(bulk__class=Field.choice, bulk__choices=choices, query__class=Variable.choice, query__choices=choices),
     )
     return Column(**kwargs)
Example #2
0
 def multi_choice(**kwargs):
     setdefaults(kwargs, dict(
         attrs={'multiple': ''},
         choice_to_option=lambda form, field, choice: (choice, unicode(choice), unicode(choice), field.value_list and choice in field.value_list),
         is_list=True
     ))
     return Field.choice(**kwargs)
Example #3
0
 def foreign_key_factory(model_field, **kwargs):
     setdefaults(
         kwargs,
         dict(choices=model_field.foreign_related_fields[0].model.
              objects.all()))
     kwargs['model'] = model_field.foreign_related_fields[0].model
     return Column.choice_queryset(**kwargs)
Example #4
0
 def email(**kwargs):
     setdefaults(
         kwargs,
         dict(bulk__class=Field.email,
              # TODO: query__class=Variable.email,
              ))
     return Column(**kwargs)
Example #5
0
    def choice_queryset(**kwargs):
        """
        Field that has one value out of a set.
        :type choices: django.db.models.QuerySet
        """
        def choice_queryset_value_to_q(variable, op, value_string_or_f):
            if op != '=':
                raise QueryException('Invalid operator "%s" for variable "%s"' % (op, variable.name))
            if variable.attr is None:
                return Q()
            if isinstance(value_string_or_f, string_types) and value_string_or_f.lower() == 'null':
                return Q(**{variable.attr: None})
            try:
                instance = kwargs['choices'].get(**{variable.value_to_q_lookup: text_type(value_string_or_f)})
            except ObjectDoesNotExist:
                return None
            return Q(**{variable.attr + '__pk': instance.pk})

        setdefaults(kwargs, dict(
            gui__class=Field.choice_queryset,
            gui__choices=kwargs['choices'],
            gui__model=kwargs['model'],
            op_to_q_op=lambda op: 'exact',
            value_to_q_lookup='name',
            value_to_q=choice_queryset_value_to_q,
        ))
        return Variable(**kwargs)
Example #6
0
    def select(is_report=False,
               checkbox_name='pk',
               show=True,
               checked=lambda x: False,
               **kwargs):
        """
        Shortcut for a column of checkboxes to select rows. This is useful for implementing bulk operations.

        :param checkbox_name: the name of the checkbox. Default is "pk", resulting in checkboxes like "pk_1234".
        :param checked: callable to specify if the checkbox should be checked initially. Defaults to False.
        """
        setdefaults(
            kwargs,
            dict(
                name='__select__',
                title='Select all',
                display_name=mark_safe('<i class="fa fa-check-square-o"></i>'),
                sortable=False,
                show=lambda table, column: evaluate(
                    show, table=table, column=column) and not is_report,
                attrs__class__thin=True,
                attrs__class__nopad=True,
                cell__attrs__class__cj=True,
                cell__value=lambda table, column, row: mark_safe(
                    '<input type="checkbox"%s class="checkbox" name="%s_%s" />'
                    % (' checked'
                       if checked(row.pk) else '', checkbox_name, row.pk)),
            ))
        return Column(**kwargs)
Example #7
0
    def __init__(self, **kwargs):
        """
        :param name: the name of the column
        :param attr: What attribute to use, defaults to same as name. Follows django conventions to access properties of properties, so "foo__bar" is equivalent to the python code `foo.bar`. This parameter is based on the variable name of the Column if you use the declarative style of creating tables.
        :param display_name: the text of the header for this column. By default this is based on the `name` parameter so normally you won't need to specify it.
        :param css_class: CSS class of the header
        :param url: URL of the header. This should only be used if "sorting" is off.
        :param title: title/tool tip of header
        :param show: set this to False to hide the column
        :param sortable: set this to False to disable sorting on this column
        :param sort_key: string denoting what value to use as sort key when this column is selected for sorting. (Or callable when rendering a table from list.)
        :param sort_default_desc: Set to True to make table sort link to sort descending first.
        :param group: string describing the group of the header. If this parameter is used the header of the table now has two rows. Consecutive identical groups on the first level of the header are joined in a nice way.
        :param auto_rowspan: enable automatic rowspan for this column. To join two cells with rowspan, just set this auto_rowspan to True and make those two cells output the same text and we'll handle the rest.
        :param cell__template: name of a template file. The template gets arguments: `table`, `bound_column`, `bound_row`, `row` and `value`.
        :param cell__value: string or callable that receives kw arguments: `table`, `column` and `row`. This is used to extract which data to display from the object.
        :param cell__format: string or callable that receives kw arguments: `table`, `column`, `row` and `value`. This is used to convert the extracted data to html output (use `mark_safe`) or a string.
        :param cell__attrs: dict of attr name to callables that receive kw arguments: `table`, `column`, `row` and `value`.
        :param cell__url: callable that receives kw arguments: `table`, `column`, `row` and `value`.
        :param cell__url_title: callable that receives kw arguments: `table`, `column`, `row` and `value`.
        """

        setdefaults(kwargs, dict(
            bulk=(Struct(extract_subkeys(kwargs, 'bulk', defaults=dict(show=False)))),
            query=(Struct(extract_subkeys(kwargs, 'query', defaults=dict(show=False)))),
            extra=(Struct(extract_subkeys(kwargs, 'extra'))),
        ))

        kwargs = {k: v for k, v in kwargs.items() if not k.startswith('bulk__') and not k.startswith('query__') and not k.startswith('extra__')}

        assert isinstance(kwargs['bulk'], dict)
        assert isinstance(kwargs['query'], dict)
        assert isinstance(kwargs['extra'], dict)

        super(Column, self).__init__(**kwargs)
Example #8
0
    def icon(icon, is_report=False, icon_title="", show=True, **kwargs):
        """
        Shortcut to create font awesome-style icons.

        :param icon: the font awesome name of the icon
        """
        setdefaults(
            kwargs,
            dict(
                name="",
                display_name="",
                sortable=False,
                attrs__class__thin=True,
                show=lambda table, **rest: evaluate(show, table=table, **rest) and not is_report,
                title=icon_title,
                cell__value=lambda table, column, row, **_: True,
                cell__attrs__class__cj=True,
                cell__format=lambda value, **_: mark_safe(
                    '<i class="fa fa-lg fa-%s"%s></i>' % (icon, ' title="%s"' % icon_title if icon_title else "")
                )
                if value
                else "",
            ),
        )
        return Column(**kwargs)
Example #9
0
    def select(is_report=False, checkbox_name="pk", show=True, checked=lambda x: False, **kwargs):
        """
        Shortcut for a column of checkboxes to select rows. This is useful for implementing bulk operations.

        :param checkbox_name: the name of the checkbox. Default is "pk", resulting in checkboxes like "pk_1234".
        :param checked: callable to specify if the checkbox should be checked initially. Defaults to False.
        """
        setdefaults(
            kwargs,
            dict(
                name="__select__",
                title="Select all",
                display_name=mark_safe('<i class="fa fa-check-square-o"></i>'),
                sortable=False,
                show=lambda table, **rest: evaluate(show, table=table, **rest) and not is_report,
                attrs__class__thin=True,
                attrs__class__nopad=True,
                cell__attrs__class__cj=True,
                cell__value=lambda row, **_: mark_safe(
                    '<input type="checkbox"%s class="checkbox" name="%s_%s" />'
                    % (" checked" if checked(row.pk) else "", checkbox_name, row.pk)
                ),
            ),
        )
        return Column(**kwargs)
Example #10
0
 def multi_choice_queryset(**kwargs):
     setdefaults(kwargs, dict(
         attrs={'multiple': ''},
         choice_to_option=should_not_evaluate(lambda form, field, choice: (choice, choice.pk, unicode(choice), field.value_list and choice in field.value_list)),
         is_list=True
     ))
     return Field.choice_queryset(**kwargs)
Example #11
0
 def integer(**kwargs):  # pragma: no cover
     """
     Boolean field. Tries hard to parse a boolean value from its input.
     """
     setdefaults(kwargs, dict(
         gui__class=Field.integer,
     ))
     return Variable(**kwargs)
Example #12
0
 def number(**kwargs):
     """
     Shortcut for rendering a number. Sets the "rj" (as in "right justified") CSS class on the cell and header.
     """
     setdefaults(kwargs, dict(
         cell__attrs__class__rj=True
     ))
     return Column(**kwargs)
Example #13
0
 def choice_queryset(**kwargs):
     model = kwargs.pop('model')
     setdefaults(kwargs, dict(
         extra=Struct(model=model),
         parse=lambda form, field, string_value: field.extra.model.objects.get(pk=string_value) if string_value else None,
         choice_to_option=lambda form, field, choice: (choice, choice.pk, unicode(choice), choice == field.value)
     ))
     return Field.choice(**kwargs)
Example #14
0
 def choice_queryset(**kwargs):
     setdefaults(kwargs, dict(
         bulk__class=Field.choice_queryset,
         bulk__model=kwargs.get('model'),
         query__class=Variable.choice_queryset,
         query__model=kwargs.get('model'),
     ))
     return Column.choice(**kwargs)
Example #15
0
 def edit(is_report=False, **kwargs):
     """
     Shortcut for creating a clickable edit icon. The URL defaults to `your_object.get_absolute_url() + 'edit/'`. Specify the option cell__url to override.
     """
     setdefaults(kwargs, dict(
         cell__url=lambda row, **_: row.get_absolute_url() + 'edit/',
         display_name=''
     ))
     return Column.icon('pencil-square-o', is_report, 'Edit', **kwargs)
Example #16
0
 def delete(is_report=False, **kwargs):
     """
     Shortcut for creating a clickable delete icon. The URL defaults to `your_object.get_absolute_url() + 'delete/'`. Specify the option cell__url to override.
     """
     setdefaults(
         kwargs,
         dict(cell__url=lambda row, **_: row.get_absolute_url() + 'delete/',
              display_name=''))
     return Column.icon('trash-o', is_report, 'Delete', **kwargs)
Example #17
0
 def download(is_report=False, **kwargs):
     """
     Shortcut for creating a clickable download icon. The URL defaults to `your_object.get_absolute_url() + 'download/'`. Specify the option cell__url to override.
     """
     setdefaults(kwargs, dict(
         cell__url=lambda row, **_: row.get_absolute_url() + 'download/',
         cell__value=lambda row, **_: getattr(row, 'pk', False),
     ))
     return Column.icon('download', is_report, 'Download', **kwargs)
Example #18
0
 def delete(is_report=False, **kwargs):
     """
     Shortcut for creating a clickable delete icon. The URL defaults to `your_object.get_absolute_url() + 'delete/'`. Specify the option cell__url to override.
     """
     setdefaults(kwargs, dict(
         cell__url=lambda row, **_: row.get_absolute_url() + 'delete/',
         display_name=''
     ))
     return Column.icon('trash-o', is_report, 'Delete', **kwargs)
Example #19
0
 def edit(is_report=False, **kwargs):
     """
     Shortcut for creating a clickable edit icon. The URL defaults to `your_object.get_absolute_url() + 'edit/'`. Specify the option cell__url to override.
     """
     setdefaults(
         kwargs,
         dict(cell__url=lambda row, **_: row.get_absolute_url() + 'edit/',
              display_name=''))
     return Column.icon('pencil-square-o', is_report, 'Edit', **kwargs)
Example #20
0
 def choice_queryset(**kwargs):
     setdefaults(
         kwargs,
         dict(
             bulk__class=Field.choice_queryset,
             bulk__model=kwargs.get('model'),
             query__class=Variable.choice_queryset,
             query__model=kwargs.get('model'),
         ))
     return Column.choice(**kwargs)
Example #21
0
 def time(**kwargs):
     def parse_time(string_value, **_):
         try:
             return datetime.strptime(string_value, '%H:%M:%S').time()
         except ValueError as e:
             raise ValidationError(e.message)
     setdefaults(kwargs, dict(
         parse=parse_time
     ))
     return Field(**kwargs)
Example #22
0
 def inline_edit(base=ColumnBase, **kwargs):
     setdefaults(
         kwargs,
         dict(
             cell__format=lambda table, column, row, value: mark_safe(
                 '<span class="inline_editable" edit_url="%sedit/%s/" id="%s">%s</span>'
                 % (row.get_absolute_url(), column.name, row.pk, value)),
             query__show=True,
         ))
     return base(**kwargs)
Example #23
0
 def choice(**kwargs):  # pragma: no cover
     """
     Field that has one value out of a set.
     :type choices: list
     """
     setdefaults(kwargs, dict(
         gui__choices=kwargs.get('choices'),
         gui__class=Field.choice,
     ))
     return Variable(**kwargs)
Example #24
0
 def time(**kwargs):
     setdefaults(
         kwargs,
         dict(
             query__class=Variable.time,
             query__op_to_q_op=lambda op: {"=": "exact", ":": "contains"}.get(op) or Q_OP_BY_OP[op],
             bulk__class=Field.time,
         ),
     )
     return Column(**kwargs)
Example #25
0
 def choice(**kwargs):
     choices = kwargs['choices']
     setdefaults(
         kwargs,
         dict(
             bulk__class=Field.choice,
             bulk__choices=choices,
             query__class=Variable.choice,
             query__choices=choices,
         ))
     return Column(**kwargs)
Example #26
0
    def link(**kwargs):
        """
        Shortcut for creating a cell that is a link. The URL is the result of calling `get_absolute_url()` on the object.
        """
        def url(table, column, row, value):
            del table, value
            r = getattr_path(row, column.attr)
            return r.get_absolute_url() if r else ''

        setdefaults(kwargs, dict(cell__url=url, ))
        return Column(**kwargs)
Example #27
0
 def inline_edit(base=ColumnBase, **kwargs):
     setdefaults(
         kwargs,
         dict(
             cell__format=lambda table, column, row, value: mark_safe(
                 '<span class="inline_editable" edit_url="%sedit/%s/" id="%s">%s</span>'
                 % (row.get_absolute_url(), column.name, row.pk, value)
             ),
             query__show=True,
         ),
     )
     return base(**kwargs)
Example #28
0
 def datetime(**kwargs):
     setdefaults(
         kwargs,
         dict(
             query__gui__class=Field.date,
             query__op_to_q_op=lambda op: {
                 '=': 'exact',
                 ':': 'contains'
             }.get(op) or Q_OP_BY_OP[op],
             bulk__class=Field.date,
         ))
     return Column(**kwargs)
Example #29
0
    def choice(**kwargs):
        """
        Shortcut for single choice field. If required is false it will automatically add an option first with the value '' and the title '---'. To override that text pass in the parameter empty_label.
        :param empty_label: default '---'
        :param choices: list of objects
        :param choice_to_option: callable with three arguments: form, field, choice. Convert from a choice object to a tuple of (choice, value, label, selected), the last three for the <option> element
        """
        assert 'choices' in kwargs

        setdefaults(kwargs, dict(
            required=True,
            is_list=False,
            empty_label='---'
        ))

        if not kwargs['required'] and not kwargs['is_list']:
            original_choices = kwargs['choices']

            def choices(form, field):
                return [None] + list(evaluate(original_choices, form=form, field=field))

            original_parse = kwargs.get('parse', default_parse)

            def parse(form, field, string_value):
                if string_value == '':
                    return None
                return original_parse(form=form, field=field, string_value=string_value)

            kwargs.update(
                choices=choices,
                parse=parse
            )

        def choice_is_valid(form, field, parsed_data):
            del form
            if not field.required and parsed_data is None:
                return True, ''

            return parsed_data in field.choices, '%s not in available choices' % parsed_data

        def choice_post_validation(form, field):
            field.choice_tuples = [field.choice_to_option(form=form, field=field, choice=choice) if choice is not None else field.empty_choice_tuple
                                   for choice in field.choices]

        setdefaults(kwargs, dict(
            empty_choice_tuple=(None, '', kwargs['empty_label'], True),
            choice_to_option=lambda form, field, choice: (choice, unicode(choice), unicode(choice), choice == field.value),
            input_template='tri_form/choice.html',
            is_valid=choice_is_valid,
            post_validation=choice_post_validation
        ))
        kwargs['choice_to_option'] = should_not_evaluate(kwargs['choice_to_option'])
        return Field(**kwargs)
Example #30
0
 def multi_choice_queryset(**kwargs):
     setdefaults(
         kwargs,
         dict(
             bulk__class=Field.multi_choice_queryset,
             bulk__model=kwargs.get('model'),
             query__class=Variable.multi_choice_queryset,
             query__model=kwargs.get('model'),
             cell__format=lambda value, **_: ', '.join(
                 ['%s' % x for x in value.all()]),
         ))
     return Column.choice(**kwargs)
Example #31
0
    def link(**kwargs):
        """
        Shortcut for creating a cell that is a link. The URL is the result of calling `get_absolute_url()` on the object.
        """

        def url(table, column, row, value):
            del table, value
            r = getattr_path(row, column.attr)
            return r.get_absolute_url() if r else ""

        setdefaults(kwargs, dict(cell__url=url))
        return Column(**kwargs)
Example #32
0
 def multi_choice_queryset(**kwargs):
     setdefaults(
         kwargs,
         dict(
             bulk__class=Field.multi_choice_queryset,
             bulk__model=kwargs.get("model"),
             query__class=Variable.multi_choice_queryset,
             query__model=kwargs.get("model"),
             cell__format=lambda value, **_: ", ".join(["%s" % x for x in value.all()]),
         ),
     )
     return Column.choice(**kwargs)
Example #33
0
 def boolean(**kwargs):
     """
     Boolean field. Tries hard to parse a boolean value from its input.
     """
     setdefaults(kwargs, dict(
         parse=lambda string_value, **_: bool_parse(string_value),
         required=False,
         template='tri_form/{style}_form_row_checkbox.html',
         input_template='tri_form/checkbox.html',
         is_boolean=True
     ))
     return Field(**kwargs)
Example #34
0
 def download(is_report=False, **kwargs):
     """
     Shortcut for creating a clickable download icon. The URL defaults to `your_object.get_absolute_url() + 'download/'`. Specify the option cell__url to override.
     """
     setdefaults(
         kwargs,
         dict(
             cell__url=lambda row, **_: row.get_absolute_url() +
             'download/',
             cell__value=lambda row, **_: getattr(row, 'pk', False),
         ))
     return Column.icon('download', is_report, 'Download', **kwargs)
Example #35
0
 def heading(label, show=True, template='tri_form/heading.html', **kwargs):
     """
     Shortcut to create a fake input that performs no parsing but is useful to separate sections of a form.
     """
     setdefaults(kwargs, dict(
         label=label,
         show=show,
         template=template,
         editable=False,
         attr=None,
         name='@@heading@@',
     ))
     return Field(**kwargs)
Example #36
0
 def run(is_report=False, show=True, **kwargs):
     """
     Shortcut for creating a clickable run icon. The URL defaults to `your_object.get_absolute_url() + 'run/'`. Specify the option cell__url to override.
     """
     setdefaults(kwargs, dict(
         name='',
         title='Run',
         sortable=False,
         css_class={'thin'},
         cell__url=lambda row, **_: row.get_absolute_url() + 'run/',
         cell__value='Run',
         show=lambda table, column: evaluate(show, table=table, column=column) and not is_report,
     ))
     return Column(**kwargs)
Example #37
0
    def boolean(**kwargs):  # pragma: no cover
        """
        Boolean field. Tries hard to parse a boolean value from its input.
        """
        def boolean_value_to_q(variable, op, value_string_or_f):
            if isinstance(value_string_or_f, string_types):
                value_string_or_f = bool_parse(value_string_or_f)
            return default_value_to_q(variable, op, value_string_or_f)

        setdefaults(kwargs, dict(
            gui__class=Field.boolean,
            value_to_q=boolean_value_to_q,
        ))
        return Variable(**kwargs)
Example #38
0
    def __init__(self, **kwargs):
        """        
        Note that, in addition to the parameters with the defined behavior below, you can pass in any keyword argument you need yourself, including callables that conform to the protocol, and they will be added and evaluated as members.
        
        All these parameters can be callables, and if they are, will be evaluated with the keyword arguments form and field. The only exceptions are is_valid (which gets form, field and parsed_data), render_value (which takes form, field and value) and parse (which gets form, field, string_value). Example of using a lambda to specify a value:
        
        .. code:: python

            Field(id=lambda form, field: 'my_id_%s' % field.name)
        
        :param name: the name of the field. This is the key used to grab the data from the form dictionary (normally request.GET or request.POST) 
        :param is_valid: validation function. Should return a tuple of (bool, reason_for_failure_if_bool_is_false) or raise ValidationError. Default: lambda form, field, parsed_data: (True, '')
        :param parse: parse function. Default just returns the string input unchanged: lambda form, field, string_value: string_value
        :param initial: initial value of the field 
        :param attr: the attribute path to apply or get the data from. For example using "foo__bar__baz" will result in `your_instance.foo.bar.baz` will be set by the apply() function. Defaults to same as name
        :param id: the HTML id attribute. Default: 'id_%s' % name
        :param label: the text in the HTML label tag. Default: capitalize(name).replace('_', ' ')
        :param template: django template filename for the entire row. Normally you shouldn't need to override on this level, see input_template, label_template and error_template below. Default: 'tri_form/{style}_form_row.html'
        :param template_string: You can inline a template string here if it's more convenient than creating a file. Default: None
        :param input_template: django template filename for the template for just the input control. Default: 'tri_form/input.html'
        :param label_template: django template filename for the template for just the label tab. Default: 'tri_form/label.html'
        :param errors_template: django template filename for the template for just the errors output. Default: 'tri_form/errors.html'
        :param required: if the field is a required field. Default: True
        :param container_css_classes: extra CSS classes to set on the container (i.e. row if rendering as a table). Default: set()
        :param label_container_css_classes: default: {'description_container'}
        :param input_container_css_classes: default: set()
        :param help_text: The help text will be grabbed from the django model if specified and available. Default: lambda form, field: '' if form.model is None else form.model._meta.get_field_by_name(field.name)[0].help_text or ''

        :param editable: default: True
        :param strip_input: runs the input data through standard python .strip() before passing it to the parse function (can NOT be callable). Default: True
        :param input_type: the type attribute on the standard input HTML tag. Default: 'text'
        :param render_value: render the parsed and validated value into a string. Default just converts to unicode: lambda form, field, value: unicode(value)
        :param is_list: interpret request data as a list (can NOT be a callable). Default False
        """

        name = kwargs.get('name')
        if name:
            if not kwargs.get('attr'):
                kwargs['attr'] = name
            if not kwargs.get('id'):
                kwargs['id'] = 'id_%s' % name
            if not kwargs.get('label'):
                kwargs['label'] = capitalize(name).replace('_', ' ')

        setdefaults(kwargs, dict(
            extra=Struct()
        ))

        super(Field, self).__init__(**collect_namespaces(kwargs))
Example #39
0
    def boolean(is_report=False, **kwargs):
        """
        Shortcut to render booleans as a check mark if true or blank if false.
        """
        def render_icon(value):
            if callable(value):
                value = value()
            return mark_safe('<i class="fa fa-check" title="Yes"></i>') if value else ''

        setdefaults(kwargs, dict(
            cell__format=lambda table, column, row, value: yes_no_formatter(table=table, column=column, row=row, value=value) if is_report else render_icon(value),
            cell__attrs={'class': 'cj'},
            query__class=Variable.boolean,
            bulk__class=Field.boolean,
        ))
        return Column(**kwargs)
Example #40
0
def setup():
    from tri.query import Variable
    from django.db.models import IntegerField, FloatField, TextField, BooleanField, AutoField, CharField, CommaSeparatedIntegerField, DateField, DateTimeField, DecimalField, EmailField, URLField, TimeField, ForeignKey, ManyToOneRel, ManyToManyField, ManyToManyRel

    def foreign_key_factory(model_field, **kwargs):
        setdefaults(kwargs, dict(
            choices=model_field.foreign_related_fields[0].model.objects.all()
        ))
        kwargs['model'] = model_field.foreign_related_fields[0].model
        return Variable.choice_queryset(**kwargs)

    # The order here is significant because of inheritance structure. More specific must be below less specific.
    global _variable_factory_by_django_field_type
    _variable_factory_by_django_field_type = OrderedDict([
        (CharField, lambda model_field, **kwargs: Variable(**kwargs)),
        (URLField, lambda model_field, **kwargs: Variable.url(**kwargs)),
        (TimeField, lambda model_field, **kwargs: Variable.time(**kwargs)),
        (EmailField, lambda model_field, **kwargs: Variable.email(**kwargs)),
        (DecimalField, lambda model_field, **kwargs: Variable.decimal(**kwargs)),
        (DateField, lambda model_field, **kwargs: Variable.date(**kwargs)),
        (DateTimeField, lambda model_field, **kwargs: Variable.datetime(**kwargs)),
        (CommaSeparatedIntegerField, lambda model_field, **kwargs: Variable.comma_separated(parent_field=Variable.integer(**kwargs))),
        (BooleanField, lambda model_field, **kwargs: Variable.boolean(**kwargs)),
        (TextField, lambda model_field, **kwargs: Variable.text(**kwargs)),
        (FloatField, lambda model_field, **kwargs: Variable.float(**kwargs)),
        (IntegerField, lambda model_field, **kwargs: Variable.integer(**kwargs)),
        (AutoField, lambda model_field, **kwargs: Variable.integer(**setdefaults(kwargs, dict(show=False)))),
        (ManyToOneRel, None),
        (ManyToManyField, lambda model_field, **kwargs: Variable.multi_choice_queryset(**setdefaults(kwargs, dict(choices=model_field.rel.to._default_manager.all())))),
        (ManyToManyRel, None),
        # (ManyToManyRel_Related, None),
        (ForeignKey, foreign_key_factory),
    ])
Example #41
0
    def inline_edit_select(**kwargs):
        def inline_edit_select_cell_format(table, column, row, value):
            options = '<option value=""></option>' + "\n".join(
                [
                    '<option value="%s"%s>%s</option>'
                    % (choice.pk, ' selected="selected"' if choice == value else "", choice)
                    for choice in evaluate(kwargs["choices"], table=table, column=column, row=row, value=value)
                ]
            )

            return mark_safe(
                '<select class="inline_editable_select" edit_url="%sedit/%s/" id="%s">%s</select>'
                % (row.get_absolute_url(), column.name, row.pk, options)
            )

        setdefaults(kwargs, dict(cell__format=inline_edit_select_cell_format, query__show=True))
        return ColumnBase.choice_queryset(**kwargs)
Example #42
0
 def run(is_report=False, show=True, **kwargs):
     """
     Shortcut for creating a clickable run icon. The URL defaults to `your_object.get_absolute_url() + 'run/'`. Specify the option cell__url to override.
     """
     setdefaults(
         kwargs,
         dict(
             name='',
             title='Run',
             sortable=False,
             css_class={'thin'},
             cell__url=lambda row, **_: row.get_absolute_url() + 'run/',
             cell__value='Run',
             show=lambda table, column: evaluate(
                 show, table=table, column=column) and not is_report,
         ))
     return Column(**kwargs)
Example #43
0
    def select(is_report=False, checkbox_name='pk', show=True, checked=lambda x: False, **kwargs):
        """
        Shortcut for a column of checkboxes to select rows. This is useful for implementing bulk operations.

        :param checkbox_name: the name of the checkbox. Default is "pk", resulting in checkboxes like "pk_1234".
        :param checked: callable to specify if the checkbox should be checked initially. Defaults to False.
        """
        setdefaults(kwargs, dict(
            name='__select__',
            title='Select all',
            display_name=mark_safe('<i class="fa fa-check-square-o"></i>'),
            sortable=False,
            show=lambda table, column: evaluate(show, table=table, column=column) and not is_report,
            css_class={'thin', 'nopad'},
            cell__attrs={'class': 'cj'},
            cell__value=lambda table, column, row: mark_safe('<input type="checkbox"%s class="checkbox" name="%s_%s" />' % (' checked' if checked(row.pk) else '', checkbox_name, row.pk)),
        ))
        return Column(**kwargs)
Example #44
0
    def boolean(is_report=False, **kwargs):
        """
        Shortcut to render booleans as a check mark if true or blank if false.
        """
        def render_icon(value):
            if callable(value):
                value = value()
            return mark_safe(
                '<i class="fa fa-check" title="Yes"></i>') if value else ''

        setdefaults(
            kwargs,
            dict(
                cell__format=lambda table, column, row, value:
                yes_no_formatter(
                    table=table, column=column, row=row, value=value)
                if is_report else render_icon(value),
                cell__attrs__class__cj=True,
                query__class=Variable.boolean,
                bulk__class=Field.boolean,
            ))
        return Column(**kwargs)
Example #45
0
    def icon(icon, is_report=False, icon_title='', show=True, **kwargs):
        """
        Shortcut to create font awesome-style icons.

        :param icon: the font awesome name of the icon
        """
        setdefaults(
            kwargs,
            dict(name='',
                 display_name='',
                 sortable=False,
                 attrs__class__thin=True,
                 show=lambda table, column: evaluate(
                     show, table=table, column=column) and not is_report,
                 title=icon_title,
                 cell__value=lambda table, column, row: True,
                 cell__attrs__class__cj=True,
                 cell__format=lambda table, column, row, value:
                 mark_safe('<i class="fa fa-lg fa-%s"%s></i>' %
                           (icon, ' title="%s"' % icon_title
                            if icon_title else '')) if value else ''))
        return Column(**kwargs)
Example #46
0
    def inline_edit_select(**kwargs):
        def inline_edit_select_cell_format(table, column, row, value):
            options = '<option value=""></option>' + '\n'.join([
                '<option value="%s"%s>%s</option>' %
                (choice.pk, ' selected="selected"' if choice == value else '',
                 choice) for choice in evaluate(kwargs['choices'],
                                                table=table,
                                                column=column,
                                                row=row,
                                                value=value)
            ])

            return mark_safe(
                '<select class="inline_editable_select" edit_url="%sedit/%s/" id="%s">%s</select>'
                % (row.get_absolute_url(), column.name, row.pk, options))

        setdefaults(
            kwargs,
            dict(
                cell__format=inline_edit_select_cell_format,
                query__show=True,
            ))
        return ColumnBase.choice_queryset(**kwargs)
Example #47
0
 def number(**kwargs):
     """
     Shortcut for rendering a number. Sets the "rj" (as in "right justified") CSS class on the cell and header.
     """
     setdefaults(kwargs, dict(cell__attrs__class__rj=True))
     return Column(**kwargs)
Example #48
0
 def substring(**kwargs):
     setdefaults(kwargs, dict(query__gui_op=':', ))
     return Column(**kwargs)
Example #49
0
def setup_db_compat_django():
    from tri.table import Column, register_column_factory
    try:
        # noinspection PyUnresolvedReferences
        from django.db.models import IntegerField, FloatField, TextField, BooleanField, AutoField, CharField, CommaSeparatedIntegerField, DateField, DateTimeField, DecimalField, EmailField, URLField, TimeField, ForeignKey, ManyToOneRel, ManyToManyField, ManyToManyRel
        # from django.db.models.fields.reverse_related import ManyToManyRel as ManyToManyRel_Related
    except ImportError:
        pass
    else:
        # The order here is significant because of inheritance structure. More specific must be below less specific.
        register_column_factory(CharField,
                                lambda model_field, **kwargs: Column(**kwargs))
        register_column_factory(
            URLField, lambda model_field, **kwargs: Column.url(**kwargs))
        register_column_factory(
            TimeField, lambda model_field, **kwargs: Column.time(**kwargs))
        register_column_factory(
            EmailField, lambda model_field, **kwargs: Column.email(**kwargs))
        register_column_factory(
            DecimalField,
            lambda model_field, **kwargs: Column.decimal(**kwargs))
        register_column_factory(
            DateField, lambda model_field, **kwargs: Column.date(**kwargs))
        register_column_factory(
            DateTimeField,
            lambda model_field, **kwargs: Column.datetime(**kwargs))
        register_column_factory(
            CommaSeparatedIntegerField, lambda model_field, **kwargs: Column.
            comma_separated(parent_field=Column.integer(**kwargs)))
        register_column_factory(
            BooleanField,
            lambda model_field, **kwargs: Column.boolean(**kwargs))
        register_column_factory(
            TextField, lambda model_field, **kwargs: Column.text(**kwargs))
        register_column_factory(
            FloatField, lambda model_field, **kwargs: Column.float(**kwargs))
        register_column_factory(
            IntegerField,
            lambda model_field, **kwargs: Column.integer(**kwargs))
        register_column_factory(
            AutoField,
            lambda model_field, **kwargs: Column.integer(**setdefaults(
                kwargs, dict(show=False))))
        register_column_factory(ManyToOneRel, None)
        register_column_factory(
            ManyToManyField, lambda model_field, **kwargs: Column.
            multi_choice_queryset(**setdefaults(
                kwargs, dict(choices=model_field.rel.to._default_manager.all())
            )))
        register_column_factory(ManyToManyRel, None)

        # register_field_factory(ManyToManyRel_Related, None)

        def foreign_key_factory(model_field, **kwargs):
            setdefaults(
                kwargs,
                dict(choices=model_field.foreign_related_fields[0].model.
                     objects.all()))
            kwargs['model'] = model_field.foreign_related_fields[0].model
            return Column.choice_queryset(**kwargs)

        register_column_factory(ForeignKey, foreign_key_factory)