如何在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
相关产品推荐
相关产品推荐

