如何实现仅超级用户可添加/编辑模型中的featured字段?
当然有可行的方案!针对你想让仅超级用户能编辑featured字段的需求,我整理了几种常用且实用的实现方式,你可以根据项目的实际场景来选:
方案1:通过Django Admin自定义实现(最常用)
大部分后台内容管理都是在Django Admin里完成的,所以直接在这里控制权限是最直接的方式。你可以通过重写Admin类的方法来实现:
from django.contrib import admin from .models import ProductPage class ProductPageAdmin(admin.ModelAdmin): list_display = ('price', 'description', 'featured') # 方式一:通过表单控制字段可用性 def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj=None, **kwargs) # 只有超级用户能编辑featured字段,其他人看到的是禁用状态 if not request.user.is_superuser: form.base_fields['featured'].disabled = True return form # 方式二:通过只读字段列表控制(二选一即可) # def get_readonly_fields(self, request, obj=None): # readonly_fields = super().get_readonly_fields(request, obj=None) # if not request.user.is_superuser: # return readonly_fields + ('featured',) # return readonly_fields admin.site.register(ProductPage, ProductPageAdmin)
这样普通管理员登录Admin后,featured字段会变成只读/禁用状态,只有超级用户能修改它。
方案2:自定义表单(适用于前端或自定义后台页面)
如果你的项目有自己的前端表单页面(不是用Django Admin),可以在表单类里直接控制字段的显示和可用性:
from django import forms from .models import ProductPage class ProductPageForm(forms.ModelForm): class Meta: model = ProductPage fields = ['price', 'description', 'featured'] def __init__(self, *args, **kwargs): # 初始化时传入当前用户 user = kwargs.pop('user', None) super().__init__(*args, **kwargs) if user and not user.is_superuser: # 禁用字段,普通用户无法编辑 self.fields['featured'].widget.attrs['disabled'] = True # 如果你不想让普通用户看到这个字段,可以直接删除 # del self.fields['featured']
然后在视图里实例化表单时记得传入当前用户:
def product_edit(request, pk): product = ProductPage.objects.get(pk=pk) if request.method == 'POST': form = ProductPageForm(request.POST, instance=product, user=request.user) if form.is_valid(): # 注意:disabled字段的前端值不会提交到后端,需要手动保留原有值 if not request.user.is_superuser: form.instance.featured = product.featured form.save() # 这里添加重定向等后续操作 else: form = ProductPageForm(instance=product, user=request.user) return render(request, 'product_edit.html', {'form': form})
方案3:模型层面兜底控制(更安全)
如果你想从最底层的模型层面防止非超级用户修改featured字段,可以重写模型的save方法,结合用户信息来做判断:
class ProductPage(models.Model): price = models.IntegerField(blank=True) description = RichTextField(blank=True) featured = models.BooleanField(default=False) def save(self, *args, user=None, **kwargs): # 如果不是超级用户且是修改已有数据,保留原有的featured值 if user and not user.is_superuser and self.pk is not None: original_product = ProductPage.objects.get(pk=self.pk) self.featured = original_product.featured super().save(*args, **kwargs)
之后在保存模型的地方(比如Admin或视图),需要传入当前用户:
# 示例:在Admin里重写save_model方法 class ProductPageAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): # 保存时传入当前登录用户 obj.save(user=request.user)
这种方式相当于一个兜底保障,即使前端或表单的控制出了问题,模型层面也能阻止非超级用户修改featured字段。
内容的提问来源于stack exchange,提问作者Lendl Smith
相关产品推荐
相关产品推荐

