You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django实现:如何为不同社团启用应用使用权限

解决方案

1. 扩展社团模型,添加应用权限关联

首先在core/models.py中给SocietyEntity添加关联字段,用来记录该社团有权限访问的应用。推荐创建一个独立的App模型来统一管理项目中的应用,这样后台操作更直观、规范:

from django.contrib.auth import get_user_model
from django.db import models

class App(models.Model):
    name = models.CharField(max_length=50, unique=True, verbose_name="应用标识")
    display_name = models.CharField(max_length=100, verbose_name="应用名称")

    def __str__(self):
        return self.display_name

class SocietyEntity(models.Model):
    id              = models.AutoField(primary_key=True)
    referenceName   = models.CharField(max_length=200, verbose_name="Nombre")
    members         = models.ManyToManyField(get_user_model(), related_name="joined_societies")
    administrator   = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, verbose_name="Administrator", related_name="managed_societies")
    # 新增多对多字段,关联允许访问的应用
    allowed_apps = models.ManyToManyField(App, blank=True, verbose_name="允许访问的应用")

完成后执行数据库迁移:

python manage.py makemigrations
python manage.py migrate

如果不想新增App模型,也可以直接用字符串选项存储应用名称(适合小型项目):

# 定义项目内的应用选项
APP_CHOICES = [
    ('blog', '博客应用'),
    ('events', '活动管理'),
    # 补充你的其他应用
]

class SocietyEntity(models.Model):
    # 原有字段...
    allowed_apps = models.ManyToManyField(
        'self',
        through=None,
        blank=True,
        verbose_name="允许访问的应用",
        choices=APP_CHOICES,
        to_field="referenceName"
    )

2. 定制Admin站点,过滤可见应用

重写Django Admin的站点逻辑,根据当前登录用户所属/管理的社团权限,过滤后台显示的应用:

# core/admin.py
from django.contrib.admin import AdminSite
from django.contrib import admin
from django.apps import apps

class CustomAdminSite(AdminSite):
    def get_app_list(self, request, app_label=None):
        app_list = super().get_app_list(request, app_label)
        current_user = request.user

        # 超级用户默认显示所有应用
        if current_user.is_superuser:
            return app_list
        
        # 获取用户有权限的应用标识列表
        allowed_app_names = []
        # 优先获取用户管理的社团权限
        managed_societies = current_user.managed_societies.all()
        if managed_societies.exists():
            allowed_app_names = list(managed_societies.values_list('allowed_apps__name', flat=True).distinct())
        else:
            # 若无管理权限,获取用户加入的社团权限
            joined_societies = current_user.joined_societies.all()
            if joined_societies.exists():
                allowed_app_names = list(joined_societies.values_list('allowed_apps__name', flat=True).distinct())
            else:
                # 无任何社团权限,仅显示core应用
                return [app for app in app_list if app['app_label'] == 'core']
        
        # 过滤应用列表,保留允许的应用和core核心应用
        filtered_apps = []
        for app in app_list:
            if app['app_label'] in allowed_app_names or app['app_label'] == 'core':
                filtered_apps.append(app)
        return filtered_apps

# 实例化自定义Admin站点
custom_admin_site = CustomAdminSite(name='custom_admin')

# 自动注册所有模型到自定义站点(也可手动注册指定模型)
for model in apps.get_models():
    try:
        custom_admin_site.register(model)
    except admin.sites.AlreadyRegistered:
        pass

最后修改项目的urls.py,替换默认的Admin路径:

# project/urls.py
from django.contrib import admin
from core.admin import custom_admin_site

urlpatterns = [
    # 注释默认Admin路由
    # path('admin/', admin.site.urls),
    path('admin/', custom_admin_site.urls),
    # 其他路由...
]

3. 注意事项

  • 如果使用字符串选项的方式存储应用权限,需要在get_app_list中调整allowed_app_names的提取逻辑,直接读取字段值即可。
  • 若有自定义的ModelAdmin类,需确保注册到自定义的custom_admin_site上,可通过custom_admin_site.register(Model, ModelAdmin)指定。

内容的提问来源于stack exchange,提问作者GonzaloN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:46:03