使用django-formset库时FormSet关联字段无法过滤问题求助
django-formset 联动下拉过滤失效问题排查与修复
针对你遇到的联动下拉未过滤问题,结合代码细节,整理出几个关键错误点和修复方案:
1. 字段查找名不匹配
你的模型字段与表单中search_lookup配置的字段名不一致,导致搜索和过滤逻辑无法定位正确字段:
TypeCar模型用的是title字段,但type_car字段的Selectize配置写了search_lookup='name__icontains',需改为title__icontains。Car模型用的是reg_mark字段,但car字段的search_lookup写了['title__icontains'],需改为['reg_mark__icontains']。
2. filter_by参数格式错误
django-formset中filter_by的取值应为表单中依赖字段的名称,而非type_car__id。正确写法是filter_by={'type_car': 'type_car'},表示用表单里的type_car字段值,过滤当前字段对应模型的type_car外键字段。
3. 模板字段渲染方式错误
直接用{{ field }}渲染无法输出django-formset所需的自定义DOM属性(如过滤关联标识),需使用库提供的{% render_field %}标签。
修正后的表单代码
from formset.widgets import Selectize class OrderCloseForm(forms.ModelForm): type_car = forms.ModelChoiceField( label="Type_car", queryset=TypeCar.objects.all(), widget=Selectize( search_lookup='title__icontains', placeholder="First, select Type car" ), required=False, ) car = forms.ModelChoiceField( label="Car", queryset=Car.objects.all(), widget=Selectize( search_lookup=['reg_mark__icontains'], filter_by={'type_car': 'type_car'}, placeholder="Then, select a Car" ), required=False, ) class Meta: model = Order fields = ('type_car', 'car')
修正后的模板代码
{% load formset %} <head> <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> <link href="{% static 'formset/css/bootstrap5-extra.css' %}" rel="stylesheet"> <link href="{% static 'formset/css/collections.css' %}" rel="stylesheet"> <script type="module" src="{% static 'formset/js/django-formset.js' %}"></script> </head> <django-formset endpoint="{{ request.path }}" csrf-token="{{ csrf_token }}"> {{ formset.management_form }} {{ formset.non_form_errors.as_ul }} {% for form in formset %} {% for field in form %} {% render_field field %} {% endfor %} {% endfor %} </django-formset>
视图补充说明
确保视图正确处理AJAX过滤请求,可继承formset.views.FormSetView来复用内置的过滤逻辑:
from django.http import JsonResponse from formset.views import FormSetView class OrderCloseFormSetView(FormSetView): formset_class = OrderCloseFormSet template_name = 'your_template.html' def get(self, request, *args, **kwargs): if request.headers.get('X-Requested-With') == 'XMLHttpRequest' and 'filter' in request.GET: return self.filter_response(request) return super().get(request, *args, **kwargs) def filter_response(self, request): field_name = request.GET.get('field') filter_value = request.GET.get('filter') form = self.formset_class.form() widget = form.fields[field_name].widget queryset = widget.filter_queryset(filter_value) return JsonResponse([{'value': obj.pk, 'label': str(obj)} for obj in queryset], safe=False)
内容的提问来源于stack exchange,提问作者epatage
相关产品推荐
相关产品推荐

