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

如何实现仅超级用户可添加/编辑模型中的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:52:03