在我的 Django 站点中,我有几个应用程序,每个应用程序仅供特定的用户组使用。假设我有两组用户:A 和 B。我有两个应用程序:URL 以 /app1 开头的 App1 和 URL 以 /app2 开头的 App2。我想将使用 App1 的权限分配给 A 组,将 App2 分配给 B 组。来自 B 的用户永远无法访问所有以 /app1 开头的 URL,反之亦然。
我该怎么做?
你可以这样做,但我建议不要这样做。
您应该在实现和 的视图上使用user_passes_test()或装饰器。permission_required()App1App2
这可以通过添加如下内容来实现:
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):
...
Run Code Online (Sandbox Code Playgroud)
为了按照要求实现这一点(根据url 前缀进行一次检查),每个应用程序必须有一个视图,可以通过如下 url 模式访问:
url(r'^app1/(?P<remaining_url>.*)$', 'app1.views.app1`)
Run Code Online (Sandbox Code Playgroud)
然后,您的视图必须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
Run Code Online (Sandbox Code Playgroud)
但解析和分派操作正是 Django 中 urlconf 的用途。
理论上,您可以创建另一个特定于应用程序的 urlconf(未从 main 引用urls.py)并手动使用其 API 重新分派remaining_url到一组视图。
这是在组下添加应用程序的所有现有权限的代码。例如,如果您有 App1 和 App2,并且您想自动创建 2 个名为 app1 和 app2 的组,其中包含对每个应用程序模型的权限(分别),请尝试以下操作:
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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
对 App2 做同样的事情
然后将用户分配到他们的组。
用途:
from .apps import App1Config
def is_in_group_app1(user):
return user.groups.filter(name=App1Config.name).exists()
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
对于 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')
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
{% 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 %}
Run Code Online (Sandbox Code Playgroud)
我花了一段时间才找到所有这些过程,所以如果它可以帮助其他人:
| 归档时间: |
|
| 查看次数: |
4938 次 |
| 最近记录: |