如何构建支持客户仅访问已购模块的Django动态模块系统?
实现Django客户模块权限控制的分步方案
1. 初始化Django项目
- 创建项目:
django-admin startproject module_access_system - 进入项目目录:
cd module_access_system - 创建核心功能app(处理用户权限、模块管理):
python manage.py startapp core - 为5个模块分别创建独立app:
python manage.py startapp module1、python manage.py startapp module2,以此类推到module5(独立app更便于后续动态管理)
2. 设计核心数据模型
在core/models.py中定义模块和用户权限关联的模型:
from django.db import models from django.contrib.auth.models import User # 模块信息表 class Module(models.Model): name = models.CharField(max_length=100, unique=True) slug = models.SlugField(unique=True) # 用于路由识别,比如module1、module2 description = models.TextField(blank=True) def __str__(self): return self.name # 用户已购模块关联表 class UserModuleAccess(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='accessible_modules') module = models.ForeignKey(Module, on_delete=models.CASCADE) purchased_at = models.DateTimeField(auto_now_add=True) class Meta: unique_together = ('user', 'module') # 防止用户重复购买同一模块
执行数据库迁移:
python manage.py makemigrations python manage.py migrate
3. 实现权限校验逻辑
自定义视图装饰器(核心权限控制)
在core/decorators.py中编写校验用户模块权限的装饰器:
from django.shortcuts import redirect, HttpResponseForbidden from core.models import UserModuleAccess def require_module_access(module_slug): def decorator(view_func): def wrapper(request, *args, **kwargs): if not request.user.is_authenticated: return redirect('login') # 未登录跳转到登录页 # 检查用户是否已购买该模块 has_access = UserModuleAccess.objects.filter( user=request.user, module__slug=module_slug ).exists() if not has_access: return HttpResponseForbidden("你没有权限访问该模块") return view_func(request, *args, **kwargs) return wrapper return decorator
在模块视图中使用装饰器,比如module1/views.py:
from django.shortcuts import render from core.decorators import require_module_access @require_module_access('module1') def module1_dashboard(request): return render(request, 'module1/dashboard.html')
动态导航渲染(可选)
在模板(如base.html)中根据用户权限动态显示可访问的模块导航:
{% for module in request.user.accessible_modules.all %} <li><a href="{% url module.slug|add:'_dashboard' %}">{{ module.name }}</a></li> {% endfor %}
注意给每个模块的路由命名为{模块slug}_dashboard,比如module1/urls.py:
from django.urls import path from . import views urlpatterns = [ path('dashboard/', views.module1_dashboard, name='module1_dashboard'), ]
4. 模块注册与配置
在settings.py的INSTALLED_APPS中添加所有app:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'core', 'module1', 'module2', 'module3', 'module4', 'module5', ]
5. 后台管理配置
在core/admin.py中注册模型,方便后台给用户分配模块权限:
from django.contrib import admin from core.models import Module, UserModuleAccess admin.site.register(Module) class UserModuleAccessAdmin(admin.ModelAdmin): list_display = ('user', 'module', 'purchased_at') search_fields = ('user__username', 'module__name') admin.site.register(UserModuleAccess, UserModuleAccessAdmin)
如果需要实现用户自主购买流程,可以编写支付回调视图,在支付成功后自动创建UserModuleAccess记录。
6. 测试权限控制
- 创建超级用户:
python manage.py createsuperuser - 登录后台,添加5个模块(slug分别设为module1到module5)
- 创建普通用户,为其分配部分模块的访问权限
- 用普通用户登录系统,尝试访问有权限和无权限的模块,验证拦截逻辑是否生效
内容的提问来源于stack exchange,提问作者Paulo Henrique A S A
相关产品推荐
相关产品推荐

