django,当models定义的类属性中,含有choices=[],admin中渲染为input框的解决办法

当models定义的类属性中,含有choices=[]时,必须在定义的Form中,显示的声明类型,例如:ChoiceField,不然会渲染成input

 

# models.py:
class GlobalSalaryAdjustRule(models.Model):
        target_field = models.CharField(
        max_length=50,
        choices=[],  # 设置为空列表,表单中会动态设置
        verbose_name="调整字段",
        default='global_yi_ti_hua_ji_xiao'
    )
# forms.py:
class GlobalSalaryAdjustRuleForm(forms.ModelForm):
    # 明确声明为 ChoiceField
    target_field = forms.ChoiceField(
        choices=[],
        label="调整字段",
        required=True
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 从数据库获取可用的字段选项
        adjustable_fields = models.AdjustableFieldConfig.objects.filter(is_active=True)
        choices = [(field.field_name, field.display_name) for field in adjustable_fields]

        # 设置字段的choices
        self.fields['target_field'].choices = choices

        # 如果没有选项,设置一个空选项
        if not choices:
            self.fields['target_field'].choices = [('', '暂无可用字段')]

        # 设置初始值
        if not self.instance.pk and choices:
            self.fields['target_field'].initial = choices[0][0]
        elif self.instance.pk and self.instance.target_field:
            # 确保编辑现有实例时显示正确的值
            self.fields['target_field'].initial = self.instance.target_field

    class Meta:
        model = models.GlobalSalaryAdjustRule
        fields = '__all__'

# admin.py:
@admin.register(app01_models.GlobalSalaryAdjustRule)
class GlobalSalaryAdjustRuleAdmin(admin.ModelAdmin):
    form = app01_forms.GlobalSalaryAdjustRuleForm  # 确保这里指向正确的表单
    list_display = [
        'name', 'rule_type', 'start_date', 'end_date', 'attendance_threshold', 'adjust_amount',
        'target_salary_month', 'is_active'
    ]
    list_filter = ['rule_type', 'is_active']
    actions = ['apply_selected_rules']

    def apply_selected_rules(self, request, queryset):
        """
        只应用选中的规则,而不是所有启用的规则
        """
        # 获取选中的规则ID列表
        selected_rules_ids = list(queryset.values_list('id', flat=True))

        # 调用应用函数,只处理选中的规则
        result = apply_selected_salary_adjustments(selected_rules_ids)

        # 显示处理结果
        success_count = result.get('success_count', 0)
        error_count = result.get('error_count', 0)
        skipped_count = result.get('skipped_count', 0)
        reverted_count = result.get('reverted_count', 0)
        filtered_count = result.get('filtered_count', 0)
        salary_bool_filtered_count = result.get('salary_bool_filtered_count', 0)

        self.message_user(
            request,
            f"已处理选中的规则。成功应用: {success_count}, 因职务设置过滤: {filtered_count}, "
            f"因工资核算设置过滤: {salary_bool_filtered_count}, 撤销调整: {reverted_count}, "
            f"失败: {error_count}, 跳过: {skipped_count}"
        )

    apply_selected_rules.short_description = "应用/更新选中的规则"

 

posted @ 2025-08-25 15:11  笑而不语心自闲  阅读(4)  评论(0)    收藏  举报