Beispiel #1
0
def paginator_number(cl, i):
    """
    Generate an individual page index link in a paginated list.
    """
    if i == DOT:
        return '... '
    elif i == cl.page_num:
        return format_html('<span class="this-page">{}</span> ', i + 1)
    else:
        return format_html(
            '<a href="{}"{}>{}</a> ', cl.get_query_string({PAGE_VAR: i}),
            mark_safe(' class="end"' if i == cl.paginator.num_pages -
                      1 else ''), i + 1)
Beispiel #2
0
    def format_callback(obj):
        model = obj.__class__
        has_admin = model in admin_site._registry
        opts = obj._meta

        no_edit_link = '%s: %s' % (capfirst(opts.verbose_name), obj)

        if has_admin:
            if not admin_site._registry[model].has_delete_permission(
                    request, obj):
                perms_needed.add(opts.verbose_name)
            try:
                admin_url = reverse(
                    '%s:%s_%s_change' %
                    (admin_site.name, opts.app_label, opts.model_name), None,
                    (quote(obj.pk), ))
            except NoReverseMatch:
                # Change url doesn't exist -- don't display link to edit
                return no_edit_link

            # Display a link to the admin page.
            return format_html('{}: <a href="{}">{}</a>',
                               capfirst(opts.verbose_name), admin_url, obj)
        else:
            # Don't display link to edit, because it either has no
            # admin or is edited inline.
            return no_edit_link
Beispiel #3
0
def _boolean_icon(field_val):
    icon_url = static('admin/img/icon-%s.svg' % {
        True: 'yes',
        False: 'no',
        None: 'unknown'
    }[field_val])
    return format_html('<img src="{}" alt="{}">', icon_url, field_val)
Beispiel #4
0
 def render_js(self):
     return [
         format_html(
             '<script type="text/javascript" src="{}"></script>',
             self.absolute_path(path)
         ) for path in self._js
     ]
Beispiel #5
0
 def label_tag(self):
     attrs = {}
     if not self.is_first:
         attrs["class"] = "inline"
     label = self.field['label']
     return format_html('<label{}>{}:</label>', flatatt(attrs),
                        capfirst(label))
Beispiel #6
0
    def as_ul(self):
        if not self.data:
            return ''

        return format_html(
            '<ul class="{}">{}</ul>', self.error_class,
            format_html_join('', '<li>{}</li>', ((e, ) for e in self)))
 def render(self, context):
     csrf_token = context.get('csrf_token')
     if csrf_token:
         if csrf_token == 'NOTPROVIDED':
             return format_html("")
         else:
             return format_html(
                 '<input type="hidden" name="csrfmiddlewaretoken" value="{}">',
                 csrf_token)
     else:
         # It's very probable that the token is missing because of
         # misconfiguration, so we raise a warning
         if settings.DEBUG:
             warnings.warn(
                 "A {% csrf_token %} was used in a template, but the context "
                 "did not provide the value.  This is usually caused by not "
                 "using RequestContext.")
         return ''
Beispiel #8
0
def _password_validators_help_text_html(password_validators=None):
    """
    Return an HTML string with all help texts of all configured validators
    in an <ul>.
    """
    help_texts = password_validators_help_texts(password_validators)
    help_items = format_html_join('', '<li>{}</li>',
                                  ((help_text, ) for help_text in help_texts))
    return format_html('<ul>{}</ul>', help_items) if help_items else ''
Beispiel #9
0
 def render_css(self):
     # To keep rendering order consistent, we can't just iterate over items().
     # We need to sort the keys, and iterate over the sorted list.
     media = sorted(self._css)
     return chain.from_iterable([
         format_html(
             '<link href="{}" type="text/css" media="{}" rel="stylesheet">',
             self.absolute_path(path), medium
         ) for path in self._css[medium]
     ] for medium in media)
Beispiel #10
0
    def label_tag(self, contents=None, attrs=None, label_suffix=None):
        """
        Wrap the given contents in a <label>, if the field has an ID attribute.
        contents should be mark_safe'd to avoid HTML escaping. If contents
        aren't given, use the field's HTML-escaped label.

        If attrs are given, use them as HTML attributes on the <label> tag.

        label_suffix overrides the form's label_suffix.
        """
        contents = contents or self.label
        if label_suffix is None:
            label_suffix = (self.field.label_suffix if self.field.label_suffix
                            is not None else self.form.label_suffix)
        # Only add the suffix if the label does not end in punctuation.
        # Translators: If found as last label character, these punctuation
        # characters will prevent the default label_suffix to be appended to the label
        if label_suffix and contents and contents[-1] not in _(':?.!'):
            contents = format_html('{}{}', contents, label_suffix)
        widget = self.field.widget
        id_ = widget.attrs.get('id') or self.auto_id
        if id_:
            id_for_label = widget.id_for_label(id_)
            if id_for_label:
                attrs = {**(attrs or {}), 'for': id_for_label}
            if self.field.required and hasattr(self.form,
                                               'required_css_class'):
                attrs = attrs or {}
                if 'class' in attrs:
                    attrs['class'] += ' ' + self.form.required_css_class
                else:
                    attrs['class'] = self.form.required_css_class
            attrs = flatatt(attrs) if attrs else ''
            contents = format_html('<label{}>{}</label>', attrs, contents)
        else:
            contents = conditional_escape(contents)
        return mark_safe(contents)
Beispiel #11
0
def display_for_field(value, field, empty_value_display):
    from server.contrib.admin.templatetags.admin_list import _boolean_icon

    if getattr(field, 'flatchoices', None):
        return dict(field.flatchoices).get(value, empty_value_display)
    # BooleanField needs special-case null-handling, so it comes before the
    # general null test.
    elif isinstance(field, models.BooleanField):
        return _boolean_icon(value)
    elif value is None:
        return empty_value_display
    elif isinstance(field, models.DateTimeField):
        return formats.localize(timezone.template_localtime(value))
    elif isinstance(field, (models.DateField, models.TimeField)):
        return formats.localize(value)
    elif isinstance(field, models.DecimalField):
        return formats.number_format(value, field.decimal_places)
    elif isinstance(field, (models.IntegerField, models.FloatField)):
        return formats.number_format(value)
    elif isinstance(field, models.FileField) and value:
        return format_html('<a href="{}">{}</a>', value.url, value)
    else:
        return display_for_value(value, empty_value_display)
Beispiel #12
0
def items_for_result(cl, result, form):
    """
    Generate the actual list of data.
    """
    def link_in_col(is_first, field_name, cl):
        if cl.list_display_links is None:
            return False
        if is_first and not cl.list_display_links:
            return True
        return field_name in cl.list_display_links

    first = True
    pk = cl.lookup_opts.pk.attname
    for field_index, field_name in enumerate(cl.list_display):
        empty_value_display = cl.model_admin.get_empty_value_display()
        row_classes = [
            'field-%s' % _coerce_field_name(field_name, field_index)
        ]
        try:
            f, attr, value = lookup_field(field_name, result, cl.model_admin)
        except ObjectDoesNotExist:
            result_repr = empty_value_display
        else:
            empty_value_display = getattr(attr, 'empty_value_display',
                                          empty_value_display)
            if f is None or f.auto_created:
                if field_name == 'action_checkbox':
                    row_classes = ['action-checkbox']
                boolean = getattr(attr, 'boolean', False)
                result_repr = display_for_value(value, empty_value_display,
                                                boolean)
                if isinstance(value, (datetime.date, datetime.time)):
                    row_classes.append('nowrap')
            else:
                if isinstance(f.remote_field, models.ManyToOneRel):
                    field_val = getattr(result, f.name)
                    if field_val is None:
                        result_repr = empty_value_display
                    else:
                        result_repr = field_val
                else:
                    result_repr = display_for_field(value, f,
                                                    empty_value_display)
                if isinstance(
                        f,
                    (models.DateField, models.TimeField, models.ForeignKey)):
                    row_classes.append('nowrap')
        if str(result_repr) == '':
            result_repr = mark_safe('&nbsp;')
        row_class = mark_safe(' class="%s"' % ' '.join(row_classes))
        # If list_display_links not defined, add the link tag to the first field
        if link_in_col(first, field_name, cl):
            table_tag = 'th' if first else 'td'
            first = False

            # Display link to the result's change_view if the url exists, else
            # display just the result's representation.
            try:
                url = cl.url_for_result(result)
            except NoReverseMatch:
                link_or_text = result_repr
            else:
                url = add_preserved_filters(
                    {
                        'preserved_filters': cl.preserved_filters,
                        'opts': cl.opts
                    }, url)
                # Convert the pk to something that can be used in Javascript.
                # Problem cases are non-ASCII strings.
                if cl.to_field:
                    attr = str(cl.to_field)
                else:
                    attr = pk
                value = result.serializable_value(attr)
                link_or_text = format_html(
                    '<a href="{}"{}>{}</a>', url,
                    format_html(' data-popup-opener="{}"', value)
                    if cl.is_popup else '', result_repr)

            yield format_html('<{}{}>{}</{}>', table_tag, row_class,
                              link_or_text, table_tag)
        else:
            # By default the fields come from ModelAdmin.list_editable, but if we pull
            # the fields out of the form instead of list_editable custom admins
            # can provide fields on a per request basis
            if (form and field_name in form.fields
                    and not (field_name == cl.model._meta.pk.name
                             and form[cl.model._meta.pk.name].is_hidden)):
                bf = form[field_name]
                result_repr = mark_safe(str(bf.errors) + str(bf))
            yield format_html('<td{}>{}</td>', row_class, result_repr)
    if form and not form[cl.model._meta.pk.name].is_hidden:
        yield format_html('<td>{}</td>', form[cl.model._meta.pk.name])
Beispiel #13
0
def result_headers(cl):
    """
    Generate the list column headers.
    """
    ordering_field_columns = cl.get_ordering_field_columns()
    for i, field_name in enumerate(cl.list_display):
        text, attr = label_for_field(field_name,
                                     cl.model,
                                     model_admin=cl.model_admin,
                                     return_attr=True)
        is_field_sortable = cl.sortable_by is None or field_name in cl.sortable_by
        if attr:
            field_name = _coerce_field_name(field_name, i)
            # Potentially not sortable

            # if the field is the action checkbox: no sorting and special class
            if field_name == 'action_checkbox':
                yield {
                    "text": text,
                    "class_attrib":
                    mark_safe(' class="action-checkbox-column"'),
                    "sortable": False,
                }
                continue

            admin_order_field = getattr(attr, "admin_order_field", None)
            if not admin_order_field:
                is_field_sortable = False

        if not is_field_sortable:
            # Not sortable
            yield {
                'text': text,
                'class_attrib': format_html(' class="column-{}"', field_name),
                'sortable': False,
            }
            continue

        # OK, it is sortable if we got this far
        th_classes = ['sortable', 'column-{}'.format(field_name)]
        order_type = ''
        new_order_type = 'asc'
        sort_priority = 0
        # Is it currently being sorted on?
        is_sorted = i in ordering_field_columns
        if is_sorted:
            order_type = ordering_field_columns.get(i).lower()
            sort_priority = list(ordering_field_columns).index(i) + 1
            th_classes.append('sorted %sending' % order_type)
            new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type]

        # build new ordering param
        o_list_primary = []  # URL for making this field the primary sort
        o_list_remove = []  # URL for removing this field from sort
        o_list_toggle = []  # URL for toggling order type for this field

        def make_qs_param(t, n):
            return ('-' if t == 'desc' else '') + str(n)

        for j, ot in ordering_field_columns.items():
            if j == i:  # Same column
                param = make_qs_param(new_order_type, j)
                # We want clicking on this header to bring the ordering to the
                # front
                o_list_primary.insert(0, param)
                o_list_toggle.append(param)
                # o_list_remove - omit
            else:
                param = make_qs_param(ot, j)
                o_list_primary.append(param)
                o_list_toggle.append(param)
                o_list_remove.append(param)

        if i not in ordering_field_columns:
            o_list_primary.insert(0, make_qs_param(new_order_type, i))

        yield {
            "text":
            text,
            "sortable":
            True,
            "sorted":
            is_sorted,
            "ascending":
            order_type == "asc",
            "sort_priority":
            sort_priority,
            "url_primary":
            cl.get_query_string({ORDER_VAR: '.'.join(o_list_primary)}),
            "url_remove":
            cl.get_query_string({ORDER_VAR: '.'.join(o_list_remove)}),
            "url_toggle":
            cl.get_query_string({ORDER_VAR: '.'.join(o_list_toggle)}),
            "class_attrib":
            format_html(' class="{}"', ' '.join(th_classes))
            if th_classes else '',
        }
Beispiel #14
0
def csrf_input(request):
    return format_html(
        '<input type="hidden" name="csrfmiddlewaretoken" value="{}">',
        get_token(request))
Beispiel #15
0
 def as_ul(self):
     if not self:
         return ''
     return format_html('<ul class="errorlist">{}</ul>',
                        format_html_join('', '<li>{}{}</li>', self.items()))