[ django-admin穿梭框 ]


django-admin多对多

1. admin后台穿梭框(manytomany才可以使用)

class AssetAdmin(admin.ModelAdmin):
    form = AssetModelForm
    # 列表界面的自定义
    list_display = ['asset','level']
    filter_horizontal = ["sub_level"]

    def get_form(self, request, obj=None, **kwargs):
        # 在form表单中移除sub_level字段
        form = super().get_form(request, obj, **kwargs)
        if obj and ((obj.level <= 1) or (obj.level >= 4)):
            form.base_fields.pop('sub_level', None)  
        return form

    def get_exclude(self, request, obj=None):
        # 只在添加对象时排除sub_level字段
        if obj is None:  
            return ['sub_level']
        else:
            return super().get_exclude(request, obj=obj)


admin.site.register(System)
admin.site.register(Asset, AssetAdmin)

2. 自定义验证(有验证不通过会提示在该字段上方)

class SpecialStockCodeTypeForm(ModelForm):
    def clean_seq(self):
        seq = self.cleaned_data.get('seq')
        # 验证 seq 字段的格式
        if not re.match(r'^\d+(,\d+)*$', seq):
            raise ValidationError('Seq must be in the format "1,3,4,5".')
        return seq

    def clean_type(self):
        type = self.cleaned_data.get('type')
        # 验证 type 字段的格式
        if SpecialStockCodeType.objects.filter(type=type).exists():
            raise ValidationError('Type must be unique.')
        return type


class SpecialStockCodeTypeAdmin(admin.ModelAdmin):
    form = SpecialStockCodeTypeForm
    list_display = ['type', 'seq']

3. 自定义字段

class SpecialStockCodeAdmin(admin.ModelAdmin):
    form = SpecialStockCodeForm
    list_display = ('stock_code', 'get_type_list')
    filter_horizontal = ["type"]

    def get_type_list(self, obj):
        return ', '.join([type.type for type in obj.type.all()])

    get_type_list.short_description = 'Type' # 显示的文字