django-autocomplete-light转发ManyToMany字段返回空值如何解决
解决方案
django-autocomplete-light 完全支持转发 ManyToMany 类型字段,你遇到取值为空的问题是两处配置错误导致的,按如下步骤调整即可:
1. 修正表单的 forward 配置
默认的字符串形式 forward 仅适配单值字段(普通字段、外键),ManyToMany 是多值字段,需要用 Field 类型的 forward 显式声明,修改 forms.py 代码:
首先导入依赖:
from dal import autocomplete, forward
再修改widget的forward配置:
class InvestmentGroupModelForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(InvestmentGroupModelForm, self).__init__(*args, **kwargs) class Meta: model = models.InvestmentGroup fields = '__all__' widgets = { "lead_investor": autocomplete.ModelSelect2( url="lead-investor-autocomplete", # 替换原来的字符串数组,用Field声明多值字段 forward=[forward.Field("persons", bool=False)] ) }
bool=False参数作用是告诉组件不要把空值转换为布尔类型,保持空数组的原始形态。
2. 修正自动补全视图的过滤逻辑
你当前的查询集本身就是Person对象的集合,不需要额外跨person关联字段过滤,直接按主键筛选即可,同时建议补全关键词搜索逻辑:
class LeadInvestorAutoComplete(autocomplete.Select2QuerySetView): def get_queryset(self): # 请务必根据访问者权限过滤返回结果! if not self.request.user.is_authenticated: return models.Person.objects.none() qs = models.Person.objects.all() persons = self.forwarded.get('persons', None) if persons: # 直接按id过滤即可,无需加person__前缀 qs = qs.filter(id__in=persons) # 补全关键词搜索逻辑 if self.q: qs = qs.filter(name__icontains=self.q) return qs
效果验证
调整完成后,在表单中先选中几个persons字段的选项,再触发lead_investor的自动补全,此时接口拿到的persons就是你选中的用户主键数组,下拉选项也只会限定在已选中的persons范围内。如果是编辑已有数据的表单,初始化时persons已有值的情况下,打开页面就能直接拿到对应值。
内容的提问来源于stack exchange,提问作者Msv
相关产品推荐
相关产品推荐

