基于用户类型实现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
相关产品推荐
相关产品推荐

