基于Django搭建多公司库存管理系统的权限控制问题
Django多企业库存管理系统的权限与Auth实现方案
一、核心数据模型设计
先明确企业-用户-库存的关联逻辑,用OneToMany关系实现数据隔离:
# models.py from django.contrib.auth.models import AbstractUser from django.db import models class Company(models.Model): name = models.CharField(max_length=100, unique=True) # 可扩展企业信息:地址、联系人等 created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.name # 扩展Django用户模型,绑定所属企业 class User(AbstractUser): company = models.ForeignKey(Company, on_delete=models.CASCADE, null=True, blank=True) # 可选:区分企业内角色 ROLE_CHOICES = ( ('admin', '企业管理员'), ('staff', '普通员工'), ) role = models.CharField(max_length=10, choices=ROLE_CHOICES, default='staff') class Inventory(models.Model): name = models.CharField(max_length=200) quantity = models.IntegerField() company = models.ForeignKey(Company, on_delete=models.CASCADE) # 可扩展库存信息:规格、入库时间等 def __str__(self): return f"{self.name} - {self.company.name}"
记得在settings.py中配置自定义用户模型:
AUTH_USER_MODEL = 'your_app.User'
二、用户认证与注册逻辑
- 企业注册:先创建
Company实例,再为该企业创建管理员账号并绑定企业。 - 员工注册:由企业管理员创建,或注册时强制选择所属企业(可限制仅企业管理员能添加员工)。
- 登录验证:直接使用Django自带认证系统,登录后用户对象会携带
company属性,用于后续权限判断。
三、核心权限控制实现
1. 视图层:自定义Mixin实现自动数据过滤
创建通用Mixin,让需权限控制的视图继承,自动筛选当前用户所属企业的数据:
# mixins.py from django.contrib.auth.mixins import LoginRequiredMixin class CompanyPermissionMixin(LoginRequiredMixin): def get_queryset(self): # 过滤当前用户企业的所有数据 queryset = super().get_queryset() return queryset.filter(company=self.request.user.company) # 表单提交时自动绑定当前企业 def form_valid(self, form): form.instance.company = self.request.user.company return super().form_valid(form)
使用示例(库存列表/创建视图):
# views.py from django.views.generic import ListView, CreateView from .models import Inventory from .mixins import CompanyPermissionMixin class InventoryListView(CompanyPermissionMixin, ListView): model = Inventory template_name = 'inventory/list.html' class InventoryCreateView(CompanyPermissionMixin, CreateView): model = Inventory fields = ['name', 'quantity'] template_name = 'inventory/create.html' success_url = '/inventory/list/'
2. 模板层:角色权限判断(可选)
在模板中根据用户角色展示对应操作:
{% if user.role == 'admin' %} <a href="{% url 'inventory_create' %}">新增库存</a> {% endif %} {% for item in object_list %} <div>{{ item.name }} - 数量: {{ item.quantity }}</div> {% endfor %}
3. 管理后台权限限制
修改Admin配置,让企业管理员仅能查看/操作本企业数据:
# admin.py from django.contrib import admin from .models import Company, User, Inventory class UserAdmin(admin.ModelAdmin): def get_queryset(self, request): qs = super().get_queryset(request) # 超级管理员可见所有用户,企业管理员仅见本企业用户 if request.user.is_superuser: return qs return qs.filter(company=request.user.company) # 限制企业管理员只能添加本企业员工 def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == 'company' and not request.user.is_superuser: kwargs['queryset'] = Company.objects.filter(id=request.user.company.id) return super().formfield_for_foreignkey(db_field, request, **kwargs) class InventoryAdmin(admin.ModelAdmin): def get_queryset(self, request): qs = super().get_queryset(request) if request.user.is_superuser: return qs return qs.filter(company=request.user.company) admin.site.register(Company) admin.site.register(User, UserAdmin) admin.site.register(Inventory, InventoryAdmin)
四、额外优化点
- 用Django的
permission_required装饰器,为企业管理员分配特定操作权限(如新增/修改库存)。 - 若开发API(基于DRF),可自定义权限类:
from rest_framework.permissions import BasePermission class IsSameCompany(BasePermission): def has_object_permission(self, request, view, obj): return obj.company == request.user.company
内容的提问来源于stack exchange,提问作者Ali harazimi
相关产品推荐
相关产品推荐

