首页 > 解决方案 > 在 Django 模型管理中使用水平过滤器修改多对多字段的可用和选择选项

问题描述

在 Model Admin 中,是否可以ManyToManyField horizontal_filter在可用和选择的字段中控制小部件中显示的内容?

例如,我有一个County模型和一个模型,如果 a 已经分配给 a ,我Territory想隐藏它。CountyTerritory

下面的问题是所选County对象将隐藏在“可用”和“已选择”小部件中horizontal_filter。是否可以只将它们隐藏在“可用”列中?

class TerritoryAdmin(admin.ModelAdmin):
    filter_horizontal = ('counties',)
    ordering = ('territory_name', )

    # remove counties already assigned to a territory
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == 'counties':
            assigned = Territory.objects.all(
                ).values_list('counties__fips_code', flat=True)
            kwargs["queryset"] = County.objects.exclude(fips_code__in=assigned)

        return super().formfield_for_manytomany(db_field, request, **kwargs)

标签: pythondjango

解决方案


您需要在自定义中执行此逻辑,ModelForm因为您需要在instance编辑时包含已选择的县

class TerritoryAdminForm(forms.ModelForm):

    def __init__(self, *args, instance=None, **kwargs):
        super().__init__(*args, instance=instance, **kwargs)
        counties_filter = Q(territories__isnull=True)
        if instance:
            counties_filter |= Q(territories__id=instance.id)
        self.fields['counties'].queryset = County.objects.filter(countries_filter)


@admin.register(Foo)
class TerritoryAdmin(admin.ModelAdmin):
    form = TerritoryAdminForm
    filter_horizontal = ['counties']

在不知道县和地区之间关系的名称的情况下,我假设它被命名为“地区”


推荐阅读