【问题标题】:Exclude Django admin fieldsets排除 Django 管理字段集
【发布时间】:2021-08-12 09:51:46
【问题描述】:

排除fieldsets 的最佳方法是什么,我一直在阅读不同的帖子,如下所示:

  1. Question

但我无法与他们合作。当它不是超级用户时,我想忽略以下字段集:

  • 合作伙伴设置。
  • email_user(这是一个内联而不是一个字段集

下面是admin.py代码

@admin.register(CooperationPartner, site=admin_site)
    class CooperationPartnerAdmin(model.Admin):
    
        
    
        inline_type = 'stacked'
        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_form(self, request, obj=None, change=False, **kwargs):
            """Overwrite get_form method."""
            self.fieldsets = self.fieldsets_change if obj else self.fieldsets_add
            return super().get_form(request, obj, change, **kwargs)

编辑:

根据@Ozahed 的回答,这是我目前的实现,

但它不会隐藏字段,真正缺少的是什么:

    def get_form(self, request, obj=None, change=False, **kwargs):
        """Overwrite get_form method."""
        self.fieldsets = self.fieldsets_change if obj else self.fieldsets_add
        form = super().get_form(request, obj, change, **kwargs)
        if request.user.is_staff:
            list_of_fields_to_hide = ['pool', 'custom_policy_type', 'birthday']
            for field_name in list_of_fields_to_hide:
                form.base_fields[field_name].is_hidden = True
        return super().get_form(request, obj, change, **kwargs)
    

【问题讨论】:

    标签: python django django-admin


    【解决方案1】:

    每个 Django 表单都有一个名为 base_fields 的字典,其中包含字段类,并且可以在调用 super().get_form 后访问。每个字段都有我们可以控制的属性,例如widget instance。在您的情况下,在 get_forms 内,根据请求的用户,您可能会更改字段的禁用或小部件本身

    from django.forms.widgets import HiddenInput
    
    def get_form (self, request, obj=None, change=False, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        if not request.user.is_superuser: 
    
           for field_name in list_of_fields_to_hide:
               form.base_fields[field_name].widget = HiddenInput()
           
        return form
    

    Django Field API documents

    【讨论】:

    • 所以,我应该对字段名称执行此操作,这只会使字段集 anme 像 Cooperation Partner Settings. 一样消失吗?
    • 我尝试了你的方法,我已经编辑了关于你的方法的问题,但仍然没有隐藏字段,可能缺少什么?
    • 改用form.fields[field_name].widget = forms.HiddenInput() 告诉我它是否有效
    • 正在使用的 Django 不接受 form.fields 它不在 form 目录中。
    • 即使刚刚测试过form.HiddenInput() 它也不可用。我正在使用 django 版本2.2.24