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

Django构建CRM系统:双角色用户与差异化视图实现问询

问题描述

我正在构建一套CRM系统,需要设置两类用户:管理员(5名以上)、主管(仅1名)。管理员通过Django表单录入并保存数据,仅能查看自身录入内容;主管可查看所有管理员在CRM中录入的全部数据列表及详情。

问题:如何创建这两类用户,并实现对应差异化视图(管理员仅看自身内容,主管看所有管理员内容)?


用户应用(App One)代码

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

# Create your models here.
class UsersModels(models.Model):
    Role = [
        ('Agent','Agent'),
        ('Manager','Manager'),
    ]
    TheUser = models.OneToOneField(User, on_delete=models.CASCADE)
    Rank = models.CharField(max_length=10, choices=Role, null=True)

    def __str__(self):
        return str(self.TheUser)  # 原代码返回User对象会报错,此处修正为字符串输出

业务应用(App Two)代码

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

# Create your models here.
class ExperimentalModels(models.Model):
    Name = models.CharField(max_length=12)
    Surname = models.CharField(max_length=12)
    created_by = models.ForeignKey(User, null=True, on_delete=models.CASCADE)

    def __str__(self):
        return self.Name

现有视图(Views)代码

from django.shortcuts import render, redirect
from . models import ExperimentalModels
from . forms import ExperimentalForms
from django.contrib import messages
from django.contrib.auth.models import User

# Create your views here.
def Edit(request, details_id):
    Details_Edit = ExperimentalModels.objects.get(pk=details_id)
    The_form_edit = ExperimentalForms(request.POST or None, instance=Details_Edit)
    if request.method == "POST":
        if The_form_edit.is_valid():
            The_form_edit.save()
    return render(request, 'Experiment/Edit.html',
                  {'The_form_edit':The_form_edit,
                   'Details_Edit':Details_Edit})

def Details(request, details_id):
    Details_list = ExperimentalModels.objects.get(pk=details_id)
    return render(request, 'Experiment/Details.html',
                  {'Details_list':Details_list})

def Home(request):
    ExperimentList = ExperimentalModels.objects.get(id=User)
    return render(request, 'Experiment/Home.html',
                  {'ExperimentList':ExperimentList})

def Database(request):
    The_form = ExperimentalForms
    if request.method == 'POST':
        The_form = ExperimentalForms(request.POST)
        if The_form.is_valid():
            The_form.save()
            messages.success(request, ("Addition Done!"))
            return redirect('Home')
    return render(request, 'Experiment/Database.html',{'The_form':The_form})

解决方案

1. 完善用户角色配置与数据创建

创建用户与角色关联

通过Django Shell或后台手动创建用户并绑定角色:

# 创建主管用户
manager_user = User.objects.create_user(username='manager', password='123456')
UsersModels.objects.create(TheUser=manager_user, Rank='Manager')

# 创建管理员用户(可批量创建多个)
agent_user1 = User.objects.create_user(username='agent1', password='123456')
UsersModels.objects.create(TheUser=agent_user1, Rank='Agent')

agent_user2 = User.objects.create_user(username='agent2', password='123456')
UsersModels.objects.create(TheUser=agent_user2, Rank='Agent')

模型修正

确保UsersModels的__str__方法返回字符串(原代码存在报错风险,已在上方代码中修正)。


2. 修复视图逻辑,实现权限差异化

核心逻辑

  • 验证用户登录状态,未登录用户无法访问视图
  • 获取当前用户的角色,根据角色过滤数据:
    • 主管(Manager):查看/操作所有数据
    • 管理员(Agent):仅查看/操作自己创建的数据

修正后的视图代码

from django.shortcuts import render, redirect, get_object_or_404
from .models import ExperimentalModels
from .forms import ExperimentalForms
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from app_one.models import UsersModels  # 导入用户角色模型

# 所有视图添加登录验证
@login_required
def Edit(request, details_id):
    # 获取当前用户角色
    user_role = UsersModels.objects.get(TheUser=request.user).Rank
    # 获取目标数据,不存在则返回404
    detail = get_object_or_404(ExperimentalModels, pk=details_id)
    
    # 管理员只能编辑自己创建的数据
    if user_role == 'Agent' and detail.created_by != request.user:
        messages.error(request, "无权限编辑该数据")
        return redirect('Home')
    
    form = ExperimentalForms(request.POST or None, instance=detail)
    if request.method == "POST" and form.is_valid():
        form.save()
        messages.success(request, "编辑成功")
        return redirect('Home')
    return render(request, 'Experiment/Edit.html', {'form': form, 'detail': detail})

@login_required
def Details(request, details_id):
    user_role = UsersModels.objects.get(TheUser=request.user).Rank
    detail = get_object_or_404(ExperimentalModels, pk=details_id)
    
    # 管理员只能查看自己创建的数据
    if user_role == 'Agent' and detail.created_by != request.user:
        messages.error(request, "无权限查看该数据")
        return redirect('Home')
    
    return render(request, 'Experiment/Details.html', {'detail': detail})

@login_required
def Home(request):
    user_role = UsersModels.objects.get(TheUser=request.user).Rank
    if user_role == 'Manager':
        # 主管查看所有数据
        experiment_list = ExperimentalModels.objects.all()
    else:
        # 管理员仅查看自己创建的数据
        experiment_list = ExperimentalModels.objects.filter(created_by=request.user)
    return render(request, 'Experiment/Home.html', {'experiment_list': experiment_list})

@login_required
def Database(request):
    if request.method == 'POST':
        form = ExperimentalForms(request.POST)
        if form.is_valid():
            # 自动绑定当前登录用户为数据创建者
            instance = form.save(commit=False)
            instance.created_by = request.user
            instance.save()
            messages.success(request, "数据添加成功")
            return redirect('Home')
    else:
        form = ExperimentalForms()
    return render(request, 'Experiment/Database.html', {'form': form})

关键修改点

  • 添加@login_required装饰器,限制未登录用户访问
  • 数据创建时自动绑定created_by字段,避免该字段为空
  • 使用get_object_or_404替代get,优化不存在数据时的错误处理
  • 增加角色权限校验,确保管理员只能操作自身创建的数据

3. 表单与模板补充配置

表单(ExperimentalForms)

隐藏created_by字段,防止用户手动修改:

from django import forms
from .models import ExperimentalModels

class ExperimentalForms(forms.ModelForm):
    class Meta:
        model = ExperimentalModels
        exclude = ['created_by']  # 排除创建者字段,不显示在表单中

模板示例(Home.html)

根据角色展示对应数据:

{% if user.is_authenticated %}
    <h1>CRM首页</h1>
    {% if experiment_list %}
        <ul>
            {% for item in experiment_list %}
                <li>
                    {{ item.Name }} {{ item.Surname }}
                    <a href="{% url 'Details' item.id %}">查看详情</a>
                    <a href="{% url 'Edit' item.id %}">编辑</a>
                </li>
            {% endfor %}
        </ul>
    {% else %}
        <p>暂无数据</p>
    {% endif %}
    <a href="{% url 'Database' %}">添加新数据</a>
{% else %}
    <a href="{% url 'login' %}">请登录</a>
{% endif %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:54:57