使用jinja和flask的范围数据库的树显示

时间:2018-05-16 14:38:01

标签: python flask jinja2

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,除了他自己

之外无法访问任何内容

(当我说下面,我的意思是分层次) (当我说access时,我的意思是访问数据,用户,等等)

我的数据库的每个条目都是这样的(例如,使用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,但这不应该是真的重要

我想要它获得一个漂亮的显示器,或者至少是一个可理解的显示器或那个DB,当给出一个id时。因此,如果给定admin,则显示EVERYTHING。如果给定user-1,则仅显示user-1等...

我使用了一些jinja模板,但没有任何进展,我得到的最远的是这个for循环来制作用户列表(使用宏)

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

我无法绕过如何做到这一点,布局应该是什么,我应该以什么顺序显示它们?我应该使用宏吗?模板?

提前致谢

1 个答案:

答案 0 :(得分:0)

我最终找到了解决这个问题的方法。

首先,我生成了一个包含范围所需的所有内容的字典:

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
                  }
               ]
            }
         ]
      }
   ]
}

然后我写了一个像这样的jinja模板:

{% 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 %}

这是final result