在Django中优化代码-以矩阵形式查看ManyToMany [英] Optimize code in Django - view ManyToMany as matrix

查看:110
本文介绍了在Django中优化代码-以矩阵形式查看ManyToMany的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Django中显示用户组权限,并以 Drupal样式(如矩阵)的形式显示它们。它可以工作,但是进行查询并将其绘制在模板中花费的时间太长。有什么方法可以改善我的代码吗?
视图img
上(完成),下(视图和template.html) )

I'm trying to show user group permissions in Django and show them in a "Drupal" style like a matrix. It works, but it takes too long to make the query and paint it in the template. Is there some way to improve my code? view img up(accomplished),down(views and template.html)

views:

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>


推荐答案

您的问题是您的运行次数超过4 * 200查询,每个组合或行和列(权限和组)的一个查询。通过一个查询将它们全部获取非常有用。但是,这并不容易,因为 Permission Group 之间的 ManyToMany 中间模型在 django.contrib.auth.models 中,code>模型不是明确的。您可以通过 获得该模型 Model._meta API

Your problem was that you run more than 4 * 200 queries, one query for every combination or rows and columns (permissions and groups). It is useful to get them all by one query. It is however not easy because the intermediate model of ManyToMany relationship between Permission and Group models is not explicit in django.contrib.auth.models. You can get that model by 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'  

将所有内容放在一起。最好使用更长的视图和简单的模板:

Put it all together. Prefer a longer view and simple template:

更新视图

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

这篇关于在Django中优化代码-以矩阵形式查看ManyToMany的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆