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

如何在Django认证用户间实现项目共享与访问控制

实现Django项目的多用户共享与访问控制

嘿,这个协作类需求太常见了!我之前做过类似的功能,给你一步步拆解怎么落地:

1. 修改Project模型(核心改动)

你原来的account是单外键,只能绑定一个用户,现在要改成区分项目所有者+多用户共享的结构,分两种场景适配:

场景1:仅需基础共享(无细分权限)

直接用ManyToManyField添加共享用户字段,同时把原account重命名为owner,语义更清晰:

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

class Project(models.Model):
    name = models.CharField(max_length=255, default='')
    description = models.CharField(max_length=255, default='')
    # 注意:created_at应该用auto_now_add(仅创建时赋值),原auto_now会每次更新都修改时间,不符合创建时间的定义
    created_at = models.DateTimeField(auto_now_add=True, null=True)
    updated_at = models.DateTimeField(auto_now=True, null=True)
    is_active = models.IntegerField(default=1, null=True)
    # 项目所有者,关联创建该项目的用户
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='owned_projects', null=True)
    # 共享给其他用户,blank=True允许项目暂时无共享用户
    shared_users = models.ManyToManyField(User, related_name='shared_projects', blank=True)

场景2:需要细分权限(只读/编辑/管理员)

如果要给不同共享用户设置差异化权限,就得用**中间模型(through)**存储权限信息:

# 先定义共享权限的中间表
class ProjectShare(models.Model):
    PERMISSION_CHOICES = (
        ('read', '只读'),
        ('edit', '编辑'),
        ('admin', '管理员'),
    )
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    permission = models.CharField(max_length=10, choices=PERMISSION_CHOICES, default='read')
    shared_at = models.DateTimeField(auto_now_add=True)

# 修改Project模型
class Project(models.Model):
    # 保留其他字段...
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='owned_projects', null=True)
    # 通过中间表关联共享用户,支持权限细分
    shared_users = models.ManyToManyField(User, through=ProjectShare, related_name='shared_projects', blank=True)

2. 数据库迁移

修改模型后,执行以下命令更新数据库:

python manage.py makemigrations
python manage.py migrate

提示:原account字段的历史数据会自动迁移到owner字段,不用担心数据丢失。

3. 实现共享功能的视图与前端

共享项目的视图(仅所有者可操作)

写一个视图处理“共享给指定用户”的逻辑,确保只有项目创建者能执行共享:

from django.shortcuts import get_object_or_404, redirect, render
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseForbidden
from .models import Project, ProjectShare

@login_required
def share_project(request, project_id):
    # 校验当前用户是项目所有者
    project = get_object_or_404(Project, id=project_id, owner=request.user)
    
    if request.method == 'POST':
        target_username = request.POST.get('username')
        permission = request.POST.get('permission', 'read')
        
        try:
            target_user = User.objects.get(username=target_username)
            # 避免重复共享同一用户
            if not ProjectShare.objects.filter(project=project, user=target_user).exists():
                ProjectShare.objects.create(
                    project=project,
                    user=target_user,
                    permission=permission
                )
            # 共享成功后跳回项目详情页
            return redirect('project_detail', project_id=project.id)
        except User.DoesNotExist:
            # 处理用户不存在的情况,返回提示
            return render(request, 'share_project.html', {
                'project': project,
                'error': '该用户不存在,请检查用户名'
            })
    
    # GET请求返回共享表单
    return render(request, 'share_project.html', {'project': project})

前端共享表单(share_project.html)

简单的表单让用户输入目标用户名和权限:

{% extends 'base.html' %}
{% block content %}
<h2>共享项目: {{ project.name }}</h2>
{% if error %}
<p style="color: red;">{{ error }}</p>
{% endif %}
<form method="post">
    {% csrf_token %}
    <div style="margin: 10px 0;">
        <label>目标用户名:</label>
        <input type="text" name="username" required style="margin-left: 10px;">
    </div>
    <div style="margin: 10px 0;">
        <label>权限:</label>
        <select name="permission" style="margin-left: 10px;">
            <option value="read">只读</option>
            <option value="edit">编辑</option>
            <option value="admin">管理员</option>
        </select>
    </div>
    <button type="submit">确认共享</button>
</form>
{% endblock %}

4. 实现访问控制逻辑

在所有涉及项目访问的视图中,添加权限校验:

from django.shortcuts import get_object_or_404
from django.http import HttpResponseForbidden

def project_detail(request, project_id):
    project = get_object_or_404(Project, id=project_id)
    
    # 权限判断:要么是所有者,要么是共享用户
    is_owner = request.user == project.owner
    is_shared_user = request.user in project.shared_users.all()
    
    if not is_owner and not is_shared_user:
        return HttpResponseForbidden("你没有访问该项目的权限")
    
    # 正常返回项目详情
    return render(request, 'project_detail.html', {'project': project})

如果用了细分权限,比如判断是否有编辑权限:

def edit_project(request, project_id):
    project = get_object_or_404(Project, id=project_id)
    
    # 所有者默认拥有所有权限,共享用户需要检查权限等级
    if request.user == project.owner:
        pass
    else:
        share_record = ProjectShare.objects.filter(
            project=project,
            user=request.user,
            permission__in=['edit', 'admin']
        ).first()
        if not share_record:
            return HttpResponseForbidden("你没有编辑该项目的权限")
    
    # 处理编辑逻辑...

这样一套流程下来,你就能实现完整的项目共享和访问控制功能,还能根据需求扩展更多权限类型~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:56:09