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

如何在Django中为News模型定义用户组与权限以实现分组管理

在Django中实现新闻模型的用户组与权限配置

刚好之前做过类似的内容管理权限配置,结合你的需求,咱们一步步来实现:


1. 先给News模型补充自定义权限

Django默认会给每个模型生成add、change、view、delete四个基础权限,但你需要的「批准」「撤销」是业务专属权限,得手动添加到模型的Meta类里。另外建议把status字段改成带选项的形式,业务逻辑更清晰:

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

class News(models.Model):
    title = models.CharField(max_length=255, help_text="Short title of news")
    content = models.TextField(blank=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    
    # 优化状态字段,默认设为待审核更合理
    STATUS_CHOICES = (
        (True, '已批准'),
        (False, '待审核/已撤销'),
    )
    status = models.BooleanField(default=False, choices=STATUS_CHOICES)

    class Meta:
        # 添加自定义权限
        permissions = [
            ("approve_news", "Can approve news"),
            ("revoke_news", "Can revoke news"),
        ]

修改完模型后,记得运行python manage.py makemigrations和python manage.py migrate来同步数据库。


2. 创建用户组并分配权限

有两种常用方式,按需选择:

方式一:Admin后台手动配置(适合测试/小型项目)

  1. 登录Django Admin,进入「Groups」页面
  2. 依次创建5个组:Reporters、CopyEditors、Producers、Rundown、Anchors
  3. 给每个组勾选对应权限:
    • Reporters:仅勾选「Can add news」(对应add_news权限)
    • CopyEditors:勾选「Can view news」+「Can change news」
    • Producers:勾选「Can view news」+「Can change news」+「Can approve news」+「Can revoke news」
    • Rundown/Anchors:先勾选「Can view news」,后续通过视图过滤内容

方式二:代码自动创建(适合生产环境批量部署)

可以写一个数据迁移文件,确保每次部署都能自动生成这些组和权限:

  1. 运行python manage.py makemigrations --empty your_app_name(替换成你的app名称)
  2. 在生成的空迁移文件中添加以下代码:
from django.db import migrations
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType

def create_groups_and_permissions(apps, schema_editor):
    # 获取News模型的ContentType
    News = apps.get_model('your_app_name', 'News')
    news_content_type = ContentType.objects.get_for_model(News)

    # 创建Reporters组
    reporter_group, _ = Group.objects.get_or_create(name='Reporters')
    add_perm = Permission.objects.get(content_type=news_content_type, codename='add_news')
    reporter_group.permissions.add(add_perm)

    # 创建CopyEditors组
    editor_group, _ = Group.objects.get_or_create(name='CopyEditors')
    view_perm = Permission.objects.get(content_type=news_content_type, codename='view_news')
    change_perm = Permission.objects.get(content_type=news_content_type, codename='change_news')
    editor_group.permissions.add(view_perm, change_perm)

    # 创建Producers组
    producer_group, _ = Group.objects.get_or_create(name='Producers')
    approve_perm = Permission.objects.get(content_type=news_content_type, codename='approve_news')
    revoke_perm = Permission.objects.get(content_type=news_content_type, codename='revoke_news')
    producer_group.permissions.add(view_perm, change_perm, approve_perm, revoke_perm)

    # 创建Rundown组
    rundown_group, _ = Group.objects.get_or_create(name='Rundown')
    rundown_group.permissions.add(view_perm)

    # 创建Anchors组
    anchor_group, _ = Group.objects.get_or_create(name='Anchors')
    anchor_group.permissions.add(view_perm)

class Migration(migrations.Migration):
    dependencies = [
        ('your_app_name', '0001_initial'),  # 替换成你当前的迁移文件名
    ]

    operations = [
        migrations.RunPython(create_groups_and_permissions),
    ]
  1. 运行python manage.py migrate完成创建

3. 视图层实现权限校验与内容过滤

现在要确保不同组的用户只能访问对应内容:

Reporters:仅允许创建新闻

用permission_required装饰器限制创建视图:

from django.contrib.auth.decorators import permission_required
from django.shortcuts import render, redirect
from .forms import NewsForm

@permission_required('your_app_name.add_news', login_url='/login/')
def create_news(request):
    if request.method == 'POST':
        form = NewsForm(request.POST)
        if form.is_valid():
            news = form.save(commit=False)
            news.author = request.user
            news.save()
            return redirect('news_list')
    else:
        form = NewsForm()
    return render(request, 'create_news.html', {'form': form})

CopyEditors:允许查看、修改所有新闻

@permission_required('your_app_name.view_news', login_url='/login/')
def news_list(request):
    news = News.objects.all()
    return render(request, 'news_list.html', {'news': news})

@permission_required('your_app_name.change_news', login_url='/login/')
def edit_news(request, pk):
    news = News.objects.get(pk=pk)
    # 可选:可以添加逻辑限制编辑仅能修改自己负责的新闻
    if request.method == 'POST':
        form = NewsForm(request.POST, instance=news)
        if form.is_valid():
            form.save()
            return redirect('news_list')
    else:
        form = NewsForm(instance=news)
    return render(request, 'edit_news.html', {'form': form})

Producers:允许批准/撤销新闻

添加专属视图并校验权限:

@permission_required('your_app_name.approve_news', login_url='/login/')
def approve_news(request, pk):
    news = News.objects.get(pk=pk)
    news.status = True
    news.save()
    return redirect('news_list')

@permission_required('your_app_name.revoke_news', login_url='/login/')
def revoke_news(request, pk):
    news = News.objects.get(pk=pk)
    news.status = False
    news.save()
    return redirect('news_list')

Rundown/Anchors:仅允许查看已批准新闻

在视图中过滤status=True的内容:

@permission_required('your_app_name.view_news', login_url='/login/')
def approved_news_list(request):
    news = News.objects.filter(status=True)
    # 可选:如果需要区分Rundown和Anchors的权限范围,可以添加额外过滤逻辑
    return render(request, 'approved_news_list.html', {'news': news})

4. 模板层控制操作按钮显示

在模板中通过perms变量判断用户权限,动态显示操作按钮:

{% for news in news %}
    <div class="news-item">
        <h3>{{ news.title }}</h3>
        <p>{{ news.content|truncatechars:100 }}</p>
        {% if perms.your_app_name.change_news %}
            <a href="{% url 'edit_news' news.pk %}">编辑</a>
        {% endif %}
        {% if perms.your_app_name.approve_news %}
            {% if not news.status %}
                <a href="{% url 'approve_news' news.pk %}">批准</a>
            {% else %}
                <a href="{% url 'revoke_news' news.pk %}">撤销</a>
            {% endif %}
        {% endif %}
    </div>
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:52:51