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

如何在Django Admin表单中展示过滤掉非活跃账号的选择列表?

解决Django Admin Fieldset中过滤用户选项的问题

这个问题我之前也碰到过,fieldset确实不支持直接用方法替换字段来过滤选项,不过有两种简单的办法可以实现你想要的效果,让attending_persons只显示活跃用户:

方案一:自定义ModelForm(推荐)

通过自定义表单来修改字段的查询集,admin会自动使用这个表单渲染fieldset里的字段,完全兼容fieldset的配置:

from django import forms
from django.contrib.auth.models import User  # 导入你的用户模型,如果是自定义用户就换成对应的
from .models import StudioMeetingNote

class StudioMeetingNoteForm(forms.ModelForm):
    class Meta:
        model = StudioMeetingNote
        # 可以指定具体字段,或者用__all__包含所有模型字段
        fields = ['meeting_start_time', 'meeting_end_time', 'chairman', 'secretary', 'attending_persons', 'absent_persons']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 过滤出活跃用户,替换字段的queryset
        active_users = User.objects.filter(is_active=True)
        self.fields['attending_persons'].queryset = active_users
        # 如果absent_persons也需要过滤,同理处理
        self.fields['absent_persons'].queryset = active_users

然后在你的Admin类里指定这个form:

class StudioMeetingNoteAdmin(admin.ModelAdmin):
    form = StudioMeetingNoteForm  # 新增这一行
    fieldsets = [
        ('Tijden', {'fields': ['meeting_start_time', 'meeting_end_time']}),
        ('Wie is de voorzitter/notulist', {'fields': [('chairman', 'secretary')]}),
        ('Opkomst', {'fields': [('attending_persons', 'absent_persons')]}),
    ]
    # 其他原有代码保持不变
    inlines = [OpeningAndParticularitiesInline, ActionListPointInline, RemarksPriorMeetingInline, IssuesToAddressInline, OurNextMoveInline, QuestionRoundInline]
    list_filter = ['meeting_start_time']
    search_fields = ['meeting_start_time']
    list_display = ('meeting_start_time', 'chairman', 'secretary')

方案二:重写Admin的get_form方法

如果不想单独写一个Form类,也可以直接在Admin类里重写get_form方法来动态修改字段的查询集:

from django.contrib.auth.models import User

class StudioMeetingNoteAdmin(admin.ModelAdmin):
    fieldsets = [
        ('Tijden', {'fields': ['meeting_start_time', 'meeting_end_time']}),
        ('Wie is de voorzitter/notulist', {'fields': [('chairman', 'secretary')]}),
        ('Opkomst', {'fields': [('attending_persons', 'absent_persons')]}),
    ]
    inlines = [OpeningAndParticularitiesInline, ActionListPointInline, RemarksPriorMeetingInline, IssuesToAddressInline, OurNextMoveInline, QuestionRoundInline]
    list_filter = ['meeting_start_time']
    search_fields = ['meeting_start_time']
    list_display = ('meeting_start_time', 'chairman', 'secretary')

    def get_form(self, request, obj=None, **kwargs):
        # 获取默认的form
        form = super().get_form(request, obj, **kwargs)
        # 修改attending_persons的查询集为活跃用户
        active_users = User.objects.filter(is_active=True)
        form.base_fields['attending_persons'].queryset = active_users
        # 同样处理absent_persons(如果需要的话)
        form.base_fields['absent_persons'].queryset = active_users
        return form

关键说明

  • 这两种方法本质都是修改表单字段的queryset属性,不管字段是在fieldset里还是普通的fields配置里,都能生效。
  • 注意:如果你的用户模型是自定义的,或者判断活跃的字段不是is_active,记得替换成你实际的模型和字段名。
  • 之前尝试用方法替换字段失败,是因为fieldset要求配置的是模型实际存在的字段(或表单字段),而方法返回的是自定义渲染内容,不符合fieldset的要求。

内容的提问来源于stack exchange,提问作者FAM_Maurice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:03:24