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

Django Admin非超级用户场景下排除指定fieldsets与inline的实现问题

Django Admin动态排除fieldsets及隐藏Inline的实现方案

现有代码核心问题

  1. 你在get_form方法中修改完form对象后,没有返回修改后的form,反而再次调用了super().get_form(),前面的修改全部被覆盖失效
  2. 仅修改字段的is_hidden属性只会将字段转为隐藏输入框,不会移除整个字段组,达不到隐藏字段组的效果
  3. 直接修改self.fieldsets会存在线程安全问题,Django Admin实例是单例模式,多请求场景下会互相干扰
  4. 隐藏Inline需要单独重写对应方法,无法通过修改表单字段实现

最优实现方案

1. 动态返回fieldsets

用官方推荐的get_fieldsets方法,直接根据用户权限过滤要返回的字段组,从根源上移除Cooperation Partner Settings字段组,不需要修改表单字段。

2. 动态控制Inline显示

重写对应Inline加载方法,非超级用户时移除email_user对应的Inline配置即可。

3. 修正get_form逻辑

如果需要额外修改表单字段,修改后直接返回修改后的form对象即可。

完整可运行代码

@admin.register(CooperationPartner, site=admin_site)
class CooperationPartnerAdmin(model.Admin):
    inline_type = 'stacked'
    # 定义基础inline配置,不要直接修改类属性
    base_inline_reverse = [(
        'email_user',
        {'fields': [
            'salutation', 'title', 'first_name', 'last_name', 'email',
        ]},
    )]
    reverse_delete_user = True
    form = CooperationPartnerAdminForm

    fieldsets_add = (
        (_('Personal Data'), {
            'fields': (
                'birthday', 'private_address_street',
                'private_address_house_n', 'private_address_extra',
                'private_address_postcode', 'private_address_city',
            ),
        }),
        (_('Cooperation Partner Settings'), {
            'fields': (
                'pool', 'custom_policy_type', 'custom_database_structure',
                'custom_attachments',
            )
        }),
        (_('Company Data'), {
            'fields': (
                'company', 'legal_form', 'business_address_street',
                'business_address_house_n', 'business_address_extra',
                'business_address_postcode', 'business_address_city',
                'international_prefix', 'phone_number', 'career_position',
                'loan_intermediary_permission', 'agreed_provision',
                'bank_name', 'iban', 'bic', 'account_holder',
                'sepa_direct_debit_mandate', 'status_decision_feedback',
            ),
        }),
    )

    fieldsets_change = (
        (None, {
            'fields': (
                'cooperation_partner_id', 'account_state',
            ),
        }),
    ) + fieldsets_add

    def get_fieldsets(self, request, obj=None):
        # 先获取基础的fieldsets
        base_fieldsets = self.fieldsets_change if obj else self.fieldsets_add
        # 非超级用户过滤掉Cooperation Partner Settings字段组
        if not request.user.is_superuser:
            base_fieldsets = tuple(
                fieldset for fieldset in base_fieldsets 
                if fieldset[0] != _('Cooperation Partner Settings')
            )
        return base_fieldsets

    # 如果你使用的基类通过inline_reverse加载inline,重写该方法即可
    def get_inline_reverse(self, request, obj=None):
        base_inlines = self.base_inline_reverse.copy()
        if not request.user.is_superuser:
            # 移除email_user对应的inline
            base_inlines = [item for item in base_inlines if item[0] != 'email_user']
        return base_inlines

    # 如果使用标准Django Inline,替换上面的方法为下面这个即可
    # def get_inlines(self, request, obj=None):
    #     inlines = super().get_inlines(request, obj)
    #     if not request.user.is_superuser:
    #         inlines = [inline for inline in inlines if inline != EmailUserInline]
    #     return inlines

    def get_form(self, request, obj=None, change=False, **kwargs):
        form = super().get_form(request, obj, change, **kwargs)
        # 如有额外需要隐藏的单独字段,可以在这里处理
        if not request.user.is_superuser:
            list_of_fields_to_hide = ['pool', 'custom_policy_type', 'birthday']
            for field_name in list_of_fields_to_hide:
                if field_name in form.base_fields:
                    del form.base_fields[field_name]
        return form

注意事项

  • 不要直接修改self.fieldsets、self.inlines这类类属性,单例模式下会影响所有用户的请求
  • 权限判断条件可根据业务需求调整,示例中not request.user.is_superuser代表非超级用户执行隐藏逻辑
  • 如果inline_reverse是第三方扩展提供的属性,可确认扩展是否提供动态获取方法,没有的话可以在请求方法中临时赋值使用,避免污染类属性。

内容的提问来源于stack exchange,提问作者Lutaaya Huzaifah Idris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 16:24:04