优化Django中的代码 - 将ManyToMany视为矩阵

时间:2017-08-25 21:06:35

标签: python django django-templates django-views

我正在尝试在Django中显示用户组权限,并以“Drupal”样式显示它们,就像矩阵一样。它可以工作,但是查询并在模板中绘制它需要很长时间。有没有办法改善我的代码? 查看img up(accomplished),down(views and template.html)

观点:

def GroupPermissionsView(request):

    title = "Groups Permissions"
    groups = Group.objects.all()
    permissions = Permission.objects.all()

    context = Context({
        'title': title,
        'groups': groups,
        'permissions': permissions,
    })
    return render(
        request,
        'forms_permissions.html',
        context
    )

模板:

<table class="table table-striped table-inverse table-responsive table-bordered">

  <thead>
        <tr>
            <th>Permission</th>
            {% for group in groups %}
                <th>{{ group.name }}</th>
            {% endfor %}
        </tr>
  </thead>

  <tbody>
        {% for permission in permissions %}
        <tr>
        <td><b>{{permission.name}}<b></td>
        {% for group in groups %}
             {% if permission in group.permissions.all %}
                        <td><input type="checkbox" name="" checked="checked"></input></td>
            {% else %}
                        <td><input type="checkbox" ></input></td>
            {% endif %}
        {% endfor %}

        </tr>
        {% endfor %}
  </tbody>
</table>

1 个答案:

答案 0 :(得分:2)

您的问题是您运行了超过4 * 200个查询,每个组合或行和列(权限和组)都有一个查询。通过一个查询获取它们非常有用。然而,这并不容易,因为ManyToManyPermission模型之间的Group关系的中间模型在django.contrib.auth.models中并不明确。您可以通过Model._meta API获取该模型:

>>> GroupPermissions = Permission._meta.get_field('group').through
>>> GroupPermissions
<class 'django.contrib.auth.models.Group_permissions'>
>>> GroupPermissions._meta.db_table  # the table that you use in the raw query
'auth_group_permissions'  

把它们放在一起。喜欢更长的视图和简单的模板:

更新视图

from collections import OrderedDict

GroupPermissions = Permission._meta.get_field('group').through
groups = Group.objects.all()
permissions = Permission.objects.all()
permission_group_set = set()
for x in GroupPermissions.objects.all():
    permission_group_set.add((x.permission_id, x.group_id))
# row title and cells for every permission
permission_group_table = OrderedDict([
    (permission, [(permission.id, group.id) in permission_group_set for group in groups])
    for permission in permissions
])

context = Context({
    'title': title,
    'groups': groups,
    'permission_group_table': permission_group_table,
})

更新模板

{% for permission, cells in permission_group_table.items %}
    <tr><td><b>{{permission.name}}<b></td>
    {% for cell in cells %}
        {% if cell %}
            <td><input type="checkbox" name="" checked="checked"></input></td>
        {% else %}
            <td><input type="checkbox" ></input></td>
        {%  endif %}
    {% endfor %}
    </tr>
{% endfor %}