【问题标题】:Django: Can we set permission to use an app?Django:我们可以设置使用应用程序的权限吗?
【发布时间】:2014-08-21 17:16:42
【问题描述】:

在我的 Django 站点中,我有几个应用程序,每个应用程序仅供特定的一组用户使用。假设我有 2 组用户:A 和 B。我有两个应用程序:App1 的 URL 以 /app1 开头,App2 的 URL 以 /app2 开头。我想将使用 App1 的权限分配给 A 组,将 App2 分配给 B 组。B 中的用户永远无法访问以 /app1 开头的所有 URL,反之亦然。

我该怎么做?

【问题讨论】:

标签: python django


【解决方案1】:

给定this answer

这是在组下添加应用的所有现有权限的代码。 例如,如果您有 App1 和 App2,并且您想自动创建 2 个名为 app1 和 app2 的组,分别包含对每个应用程序模型的权限,请尝试以下操作:

对于apps.py 上的App1:

from django.apps import AppConfig
from django.db.models.signals import post_migrate

class App1Config(AppConfig):
    name = 'app1'

    def ready(self):
        from .signals import populate_models
        post_migrate.connect(populate_models, sender=self)

创建一个包含以下内容的 signals.py 文件:

def populate_models(sender, **kwargs):
    from django.apps import apps
    from .apps import App1Config
    from django.contrib.auth.models import Group, Permission
    from django.contrib.contenttypes.models import ContentType

    group_app, created = Group.objects.get_or_create(name=App1Config.name)

    models = apps.all_models[App1Config.name]
    for model in models:
        content_type = ContentType.objects.get(
            app_label=App1Config.name,
            model=model
        )
        permissions = Permission.objects.filter(content_type=content_type)
        group_app.permissions.add(*permissions)

对 App2 执行相同操作

然后将用户分配到他们的组。

用法:

在每个应用程序上创建一个名为 permissions.py 的文件并添加:

from .apps import App1Config

def is_in_group_app1(user):
    return user.groups.filter(name=App1Config.name).exists() 

在views.py中使用:

from django.contrib.auth.decorators import login_required, user_passes_test
from .permissions import is_in_group_app1

@login_required(login_url='where_to_redirect')
@user_passes_test(is_in_group_app1) 
def myview(request):
    # Do your processing

对于 CBV:

@method_decorator(user_passes_test(is_in_group_app1), name='dispatch')
class LogListView(ListView):
    """ Displays all logs saved on App1 """
    model= Logger.objects.order_by('-date_created')

创建一个名为 templatestag 的文件夹和子文件夹 app1 和一个 has_perms.py 文件:

from django import template
from app1.permissions import is_in_group_app1
register = template.Library()

@register.filter
def has_perms(user):
    return is_in_group_app1(user)

在您的模板中:

{% load has_perms %}

{% if request.user|has_perms %}
    <li class="nav-item">
        <a href="{% url 'app1:log' %}" class="nav-link">
            <i class="icon-history"></i>
            <span data-i18n="nav.dash.main">App1 Log</span>
        </a>
    </li>
{% endif %}

我花了一段时间才找到所有这些过程,所以如果它可以帮助其他人:

享受 ;) !

【讨论】:

    【解决方案2】:

    可以这样做,但我建议不要这样做。

    您应该在实现App1App2 的视图上使用user_passes_test()permission_required() 装饰器。

    这可以通过添加如下内容来实现:

    def in_group_a(user):
        return user.groups.filter(name="Group A").exists()
    
    def in_group_b(user):
        return user.groups.filter(name="Group B").exists()
    
    @user_passes_test(in_group_a)
    def app1_view(request):
        ...
    
    @user_passes_test(in_group_b)
    def app2_view(request):
        ...
    

    为了按要求实现这一点(使用基于 url 前缀的 single 检查),您必须为每个应用程序提供一个视图,该视图通过以下 url 模式访问:

    url(r'^app1/(?P<remaining_url>.*)$', 'app1.views.app1`)
    

    然后您的视图必须像上面一样运行user_passes_test(),并手动解析remaining_url 参数以确定下一步该做什么:

    @user_passes_test(in_group_a)
    def app1(request, remaining_url):
        # parse remaining_url and work out what to do
    

    但是那个解析和调度操作正是 Django 中的 urlconf 的用途。

    理论上,您可以创建另一个特定于应用程序的 urlconf(未从您的主 urls.py 引用)并手动使用其 API 将 remaining_url 重新分配给一组视图。

    【讨论】:

    • 但是请您详细说明您反对它的原因吗?
    猜你喜欢
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 2013-08-18
    相关资源
    最近更新 更多