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

基于用户类型实现Django Artist模型编辑权限的最优方案

实现Artist模型编辑权限的最优方案

针对你的需求,我推荐结合Django内置的权限系统+自定义对象级权限检查,这比单纯添加users_who_can_edit多对多字段更贴合Django的设计哲学,既能利用内置的权限管理能力,又能灵活实现你要的三种用户权限逻辑。

第一步:完善Artist模型

首先给Artist模型关联艺术家对应的用户账号(因为艺术家本人是系统用户),同时可以自定义模型权限(可选,但能让权限管理更规范):

from django.conf import settings
from django.db import models

class Artist(models.Model):
    name = models.CharField(max_length=255)
    # 关联到艺术家的用户账号(一对一,一个用户对应一个艺术家)
    artist_user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="artist_profile",
        null=True, blank=True  # 如果存在无账号的艺术家,可保留空值,根据业务调整
    )
    # (可选)如果你需要额外指定其他非默认权限的可编辑用户,保留这个字段
    # users_who_can_edit = models.ManyToManyField(
    #     settings.AUTH_USER_MODEL,
    #     related_name="editable_artists",
    #     blank=True
    # )

    class Meta:
        # 自定义模型权限(Django默认会生成add/change/delete/view权限,这里额外加一个更明确的编辑权限)
        permissions = [
            ("edit_artist", "Can edit artist profile"),
        ]

    def can_edit(self, user):
        """判断给定用户是否有权限编辑当前Artist实例"""
        # 1. 超级用户直接拥有所有权限
        if user.is_superuser:
            return True
        # 2. 员工用户有权限编辑
        if user.is_staff:
            return True
        # 3. 艺术家本人(当该艺术家关联了用户账号时)
        if self.artist_user == user:
            return True
        # 4. (可选)如果你保留了users_who_can_edit字段,加上这个判断
        # if user in self.users_who_can_edit.all():
        #     return True
        # 5. (可选)如果需要给特定用户分配编辑权限,检查是否拥有自定义权限
        # if user.has_perm("your_app_name.edit_artist"):
        #     return True
        return False

第二步:在视图中应用权限检查

不管你用基于类的视图(CBV)还是函数视图,都可以复用上面的can_edit方法来做权限校验:

基于类的视图(比如UpdateView)

from django.views.generic.edit import UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from .models import Artist

class ArtistUpdateView(LoginRequiredMixin, UpdateView):
    model = Artist
    fields = ["name", ...]  # 替换成你的实际字段

    def get_object(self, queryset=None):
        obj = super().get_object(queryset=queryset)
        # 校验当前用户是否有权限编辑
        if not obj.can_edit(self.request.user):
            raise PermissionDenied("你没有权限编辑该艺术家信息")
        return obj

函数视图

from django.shortcuts import get_object_or_404, render, redirect
from django.core.exceptions import PermissionDenied
from .models import Artist
from .forms import ArtistForm

def edit_artist(request, pk):
    artist = get_object_or_404(Artist, pk=pk)
    
    # 权限校验
    if not artist.can_edit(request.user):
        raise PermissionDenied("你没有权限编辑该艺术家信息")
    
    if request.method == "POST":
        form = ArtistForm(request.POST, instance=artist)
        if form.is_valid():
            form.save()
            return redirect("artist_detail", pk=artist.pk)
    else:
        form = ArtistForm(instance=artist)
    
    return render(request, "artists/edit_artist.html", {"form": form, "artist": artist})

为什么不推荐单纯用ManyToMany字段?

  • Django已经内置了成熟的权限系统,超级用户(is_superuser)和员工(is_staff)的权限是原生支持的,不需要手动把这些用户添加到多对多字段里,减少冗余和维护成本。
  • 自定义的can_edit方法可以集中管理权限逻辑,后续要调整规则(比如新增一种有权限的用户类型),只需要修改这个方法即可,不用在多个视图里改代码。
  • 如果确实需要给特定用户分配编辑权限,结合自定义模型权限(user.has_perm(...))比多对多字段更灵活,还能通过Django admin可视化管理权限分配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:17:02