def display_as_table(views):
    headers = ('URL', 'Handler path', 'Decorators & Mixins')
    views = [row.split('||', 3) for row in sorted(views)]
    # Find the longest value in each column
    widths = [len(max(columns, key=len)) for columns in zip(*[headers] + views)]
    widths = [width  if width < 100 else 100 for width in widths]
    table_views = []

    table_views.append(
        ' | '.join('{0:<{1}}'.format(title, width) for width, title in zip(widths, headers))
    )
    table_views.append('-+-'.join('-' * width for width in widths))

    for row in views:
        if len(row[2]) > 100:
            row[2] = row[2].split(',')
            row[2] = [",".join(row[2][i:i+2]) for i in range(0, len(row[2]), 2)]

        mixins = row[2]
        if type(mixins) == list:
            i = 0
            for line in mixins:
                row[2] = line.strip()
                if i > 0:
                    row[0] = ''
                    row[1] = ''
                table_views.append(
                    ' | '.join('{0:<{1}}'.format(cdata, width) for width, cdata in zip(widths, row))
                )
                i += 1
        else:
            table_views.append(
                ' | '.join('{0:<{1}}'.format(cdata, width) for width, cdata in zip(widths, row))
            )

    return "\n".join([v for v in table_views]) + "\n"
Get list of views from dumpurls security management command
dataset/ETHPy150Open potatolondon/djangae/djangae/contrib/security/commands_utils.py/display_as_table