如何在Django模型的save方法中获取当前用户做权限校验?
解决Django模型仅超级用户可设置特定状态的问题
场景说明
你需要实现:仅超级用户能将Listing模型的status字段设为fake,普通用户无法操作。当前模型save方法无法获取当前认证用户,视图通过form.save(commit=False)后调用save()保存数据。
方案一:视图层直接校验(简单直观)
直接在视图里完成权限校验,无需修改模型:
@login_required def create_listing(request): if request.method == 'POST': # 注意修正原代码中的拼写错误:ListingingForm → ListingForm form = ListingForm(request.POST) if form.is_valid(): listing = form.save(commit=False) # 校验规则:状态为fake且当前用户不是超级用户时拦截 if listing.status == 'fake' and not request.user.is_superuser: raise PermissionDenied("只有超级用户才能设置该状态") listing.save() return redirect('booking_list') else: form = ListingForm() return render(request, 'listings/create_listing.html', {'form': form})
优势:逻辑简单直接,无需改动模型,适合仅在单个视图调用保存的场景。
方案二:模型层校验(通用型强)
如果Listing模型会在多个视图或场景中被保存,建议将权限逻辑集中在模型层,需要给save方法传递用户参数:
1. 修改模型的save方法
from django.core.exceptions import PermissionDenied class Listing(models.Model): STATUS_CHOICES = [ ('available', 'Available'), ('rented', 'Rented'), ('unavailable', 'Unavailable'), ('fake', 'Fake'), ] id = models.AutoField(primary_key=True) title = models.CharField(max_length=200) description = models.TextField() status = models.CharField(max_length=12, choices=STATUS_CHOICES, default='available') def save(self, *args, user=None, **kwargs): # 校验:状态为fake时,必须传入超级用户 if self.status == 'fake': if not user or not user.is_superuser: raise PermissionDenied("只有超级用户才能设置该状态") super().save(*args, **kwargs)
2. 在视图中调用save时传入当前用户
@login_required def create_listing(request): if request.method == 'POST': form = ListingForm(request.POST) if form.is_valid(): listing = form.save(commit=False) # 调用save时传入当前认证用户 listing.save(user=request.user) return redirect('booking_list') else: form = ListingForm() return render(request, 'listings/create_listing.html', {'form': form})
优势:权限校验逻辑统一维护在模型,所有调用save的场景都会自动生效,避免重复编写校验代码。
内容的提问来源于stack exchange,提问作者Mirzonabot Mirzonabotov
相关产品推荐
相关产品推荐

