Древовидное отображение базы данных областей видимости с дзиндзя и флягой - PullRequest
0 голосов
/ 16 мая 2018
Disclaimer: Title may not be the best way to describe what I am about to ask. If you have a better title in mind, please put it instead of mine

Я работаю над базой данных scope, которая позволит мне узнать, какой пользователь имеет доступ к какому-либо ресурсу. Проще говоря:

admin
     super-foo
          manager-foo-1
              user-1
              user-2
          manager-foo-2
              user-3
              user-4
     super-bar
          manager-bar-1
              user-5
              user-6
          manager-bar-2
              user-7
              user-8

admin имеет доступ ко всем пользователям под ним.

super-foo имеет доступ ко всем пользователям, кроме него, но не из super-bar

и т.д ... до вашей досягаемости, например user-1, который не имеет доступа ни к чему, кроме себя

(когда я говорю внизу, я имею в виду иерархически) (когда я говорю доступ, я имею в виду доступ к данным, пользователям, что угодно)

Каждая запись в моей БД выглядит следующим образом (например, с использованием manager-foo-1):

id=manager-foo-1 (I have a function that I can call to get everything on the user as the uuid is the hash key of my user DB (because i'm using their usernames here, but the ids are uuids.))
parents_id=['super-foo']
children_id=['user-1', 'user2']

Вот моя БД (я заменил uuid4 именами):

for user_scope in UserScope.scan():
    print("User {} has parents {} and childs {}".format(user_scope.id, user_scope.parents_id, user_scope.children_id))

User manager-foo has parents [super-foo] and childs [user-1, user-2]
User admin has parents None and childs [super-foo]
User super-foo has parents [admin] and childs [manager-foo]
User user-1 has parents [manager-foo] and childs None
User user-1 has parents [manager-foo] and childs None

childs устанавливаются на None, когда вы достигаете дна, но это не должно иметь значения

Что бы я хотел, чтобы получался красивый дисплей или, по крайней мере, понятный дисплей или эта БД, когда ему присваивается идентификатор. Так что если дано admin, отобразите EVERYTHING. Если указано user-1, отображается только пользователь-1 и т. Д. *

Я использовал немного jinja шаблонов, но ничего сложного, самое длинное, что у меня получилось, это цикл for для создания списка пользователей (с использованием макроса)

  {% for user in user_list %}
   {% from "user_line.html" import user_line %}
   {{user_line(user)}}
  {% endfor %}

У меня проблемы с тем, чтобы обернуть голову, как это сделать, каким должен быть макет, в каком порядке их отображать и использовать ли макросы? шаблоны?

Заранее спасибо

1 Ответ

0 голосов
/ 17 мая 2018

В итоге я нашел способ решить эту проблему.

Прежде всего, я создал словарь, содержащий все, что мне нужно:

def get_all_children_tree(uid):
    scope = get_userscope_dict(user.client_id)

    children = []
    if scope['children_id'] is None:
        ret = {
            "user": scope['id'],
            "children": None
        }
        return ret

    for child_id in scope['children_id']:
        children.append(get_all_children_tree(child_id))

    ret = {
        "user": scope['id'],
        "children": children
    }
    return ret

Это даст мне что-то вроде этого:

{
   'user':'cbf7f365-db8a-419b-9f8c-c24b2ce01361',
   'children':[
      {
         'user':'17bc0bdc-892b-4e47-b749-36c1687c0992',
         'children':[
            {
               'user':'d51056b7-60fe-437f-abe0-4a30076df4cd',
               'children':[
                  {
                     'user':'14f1963b-0f64-4431-a52f-819877d6096c',
                     'children':None
                  },
                  {
                     'user':'40765a8d-6001-4146-9d1f-ce3fd95646c7',
                     'children':None
                  }
               ]
            },
            {
               'user':'8a617821-e189-4b17-ac67-597ca79b98e9',
               'children':[
                  {
                     'user':'42af51b0-2810-4004-b063-a4789631bb2e',
                     'children':None
                  },
                  {
                     'user':'26d43e72-4e45-40c3-ab2b-98c637dde5aa',
                     'children':None
                  }
               ]
            }
         ]
      }
   ]
}

Тогда я написал шаблон дзиндзя так:

{% extends "main.html" %}
{% block body %}
    <!-- tree -->
    <style type="text/css">
        ul.tree {
            overflow-x: auto;
            white-space: nowrap;
        }
        ul.tree,
        ul.tree ul {
            width: auto;
            margin: 0;
            padding: 0;
            list-style-type: none;
        }
        ul.tree li {
            display: block;
            width: auto;
            float: left;
            vertical-align: top;
            padding: 0;
            margin: 0;
        }
        ul.tree ul li {
            background-image: url(data:image/gif;base64,R0lGODdhAQABAIABAAAAAP///ywAAAAAAQABAAACAkQBADs=);
            background-repeat: repeat-x;
            background-position: left top;
        }
        ul.tree li span {
            display: block;
            width: 5em;
          /*
            uncomment to fix levels
            height: 1.5em;
          */
            margin: 0 auto;
            text-align: center;
            white-space: normal;
            letter-spacing: normal;
        }
        </style>
        <!--[if IE gt 8]> IE 9+ and not IE -->
        <style type="text/css">
        ul.tree ul li:last-child {
          background-repeat: no-repeat;
          background-size:50% 1px;
          background-position: left top;
        }
        ul.tree ul li:first-child {
          background-repeat: no-repeat;
          background-size: 50% 1px;
          background-position: right top;
        }
        ul.tree ul li:first-child:last-child {
          background: none;
        }
        ul.tree ul li span {
          background: url(data:image/gif;base64,R0lGODdhAQABAIABAAAAAP///ywAAAAAAQABAAACAkQBADs=) no-repeat 50% top;
          background-size: 1px 0.8em;
          padding-top: 1.2em;
        }
        ul.tree ul {
          background: url(data:image/gif;base64,R0lGODdhAQABAIABAAAAAP///ywAAAAAAQABAAACAkQBADs=) no-repeat 50% top;
          background-size: 1px 0.8em;
          margin-top: 0.2ex;
          padding-top: 0.8em;
        }
        </style>
        <!-- <[endif]-->
        <!--[if lte IE 8]>
        <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript">
            /* Just to simplify HTML for the moment.
             * This could easily be replaced by inline classes.
             */
            $(function() {
              $('li:first-child').addClass('first');
              $('li:last-child').addClass('last');
              $('li:first-child:last-child').addClass('lone');
            });
        </script>
        <style type="text/css">
        ul.tree ul li {
          background-image: url(pixel.gif);
        }
        ul.tree ul li.first {
          background-image: url(left.gif);
          background-position: center top;
        }
        ul.tree ul li.last {
          background-image: url(right.gif);
          background-position: center top;
        }
        ul.tree ul li.lone {
          background: none;
        }
        ul.tree ul li span {
          background: url(child.gif) no-repeat 50% top;
          padding-top: 14px;
        }
        ul.tree ul {
          background: url(child.gif) no-repeat 50% top;
          margin-top: 0.2ex;
          padding-top: 11px;
        }
        </style>
        <[endif]-->

        <!-- page presentation -->
        <style type="text/css">
        body {
          font-family:sans-serif;
          color: #666;
          text-align: center;
        }
        A, A:visited, A:active {
          color: #c00;
          text-decoration: none;
        }
        A:hover {
          text-decoration: underline;
        }
        ul.tree,
        #wrapper {
          width: 960px;
          margin: 0 auto;
        }
        ul.tree {
          width: 650px;
        }
        p {
          margin-top: 2em;
        }
        </style>
    <div id="page-wrapper">
        <p> {{ data }}</p>
        <div id="wrapper">
            <ul class="tree">
                <li>
                    <span> {{ get_user(data['user']).username }}</span>
                    <ul>
                        {%- for child in data['children'] recursive %}
                            <li>
                                <span> {{ get_user(child['user']).username }} </span>
                                {%- if child['children'] -%}
                                    <ul>
                                        {{ loop(child['children']) }}
                                    </ul>
                                {%- endif %}
                            </li>
                        {%- endfor %}
                    </ul>
                </li>
            </ul>
        </div>
    </div>
{% endblock %}

Вот окончательный результат

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...