Django – Отключить проверку поля выбора формы

У меня есть форма, которая позволяет мне сначала выбрать тип продукта, а затем выбрать продукт. Поскольку у меня есть более 1000 продуктов, я использую следующее, чтобы отфильтровать список продуктов для повышения производительности.

У меня есть следующий inlineform в моих views.py

OrderLineFormSet = inlineformset_factory(OrderHeader, OrderLine, OrderLineForm, extra = 1) 

В моих forms.py я проверяю, есть ли уже выбранный продукт. Если выбран продукт, я показываю только продукты с таким же типом продукта, чтобы повысить производительность загрузки. Если продукт пуст, он загрузит все параметры продукта, чтобы он сохранил форму после выбора.

 class OrderLineForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(OrderLineForm, self).__init__(*args, **kwargs) self.helper = FormHelper(self) self.helper.form_show_errors = True self.helper.error_text_inline = False if self.instance.product is not None: self.fields['product'] = forms.ModelChoiceField(queryset=Product.objects.filter(product_type_id=self.instance.product_type_id), required=False) 

Это приводит к следующей форме

введите описание изображения здесь

Однако, когда я изменяю тип продукта в существующей форме (а затем использую jQuery для обновления раскрывающегося списка), я получаю сообщение об ошибке. Я знаю, это потому, что выбор не является вариантом в раскрывающемся списке.

введите описание изображения здесь

Мой вопрос: как я могу отключить эту ошибку, чтобы сохранить выбранную опцию, независимо от исходных параметров.

Ниже вы найдете мой view.py для этой формы

 def orderline_formset(request, id=None): OrderLineFormSet = inlineformset_factory(OrderHeader, OrderLine, OrderLineForm, extra = 1) orderheader = None orderid = None orderheaderid = 0 if id: orderid = OrderHeader.objects.get(pk=id) if request.POST: if orderid: form = OrderHeaderForm(request.POST, instance=orderid) formset = OrderLineFormSet(request.POST,instance=orderid) else: form = OrderHeaderForm(request.POST) formset = OrderLineFormSet(request.POST) if form.is_valid() and formset.is_valid(): if orderid: form.save() # update object else: orderid = form.save() # create object formset.instance = orderid formset.save() messages.success(request, 'Order saved succesfully!') return HttpResponseRedirect('/orderline_formset/' + str(orderid.pk)) else: # form invalid messages.error(request, 'Order save error, please check mandatory fields') else: # request.GET if orderid: invoiceheader = "" if orderid.orderheader_invoice: invoiceheader = " -- Invoice " + str(orderid.orderheader_invoice) orderheader = "Order " + str(orderid.pk) + invoiceheader orderheaderid = orderid.pk form = OrderHeaderForm(instance=orderid) formset = OrderLineFormSet(instance=orderid) else: orderheader = "New Order" orderheaderid = 0 form = OrderHeaderForm(instance=OrderHeader()) formset = OrderLineFormSet(instance=OrderHeader()) return render_to_response("order-add.html", {'form' : form,'formset': formset, 'orderheader': orderheader, 'orderheaderid': orderheaderid}, context_instance=RequestContext(request)) 

Переопределить ModelChoiceField , например:

 class MyModelChoiceField(ModelChoiceField): def to_python(self, value): try: value = super().to_python(value) except self.queryset.model.DoesNotExist: key = self.to_field_name or 'pk' value = Product.objects.filter(**{key: value}) if not value.exists(): raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice') else: value= value.first() return value 

И используйте его в своей форме.

 self.fields['product'] = MyModelChoiceField(queryset=Product.objects.filter(product_type_id=self.instance.product_type_id), required=False) 

Вы должны изменить

  self.fields['product'] = forms.ModelChoiceField(queryset=Product.objects.filter(product_type_id=self.instance.product_type_id), required=False) 

к

  self.fields['product'] = forms.ModelChoiceField(queryset=Product.objects.all(), required=False) 

Но вы уже знаете это и не хотите его по соображениям производительности, чтобы ваше другое решение меняло его на

 self.fields['product'] = ModelChoiceField(queryset=Product.objects.all(), widget=forms.HiddenInput, required=False) 

то внутри вашего шаблона вы вручную создаете тэг <select> и используете JS-дескриптор onchange event и обновляете поле продукта

 class OrderLineForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(OrderLineForm, self).__init__(*args, **kwargs) self.helper = FormHelper(self) self.helper.form_show_errors = True self.helper.error_text_inline = False self.fields['product'] = forms.ModelChoiceField( queryset=Product.objects.all()) self.fields['product'].required = False 

После этого вы можете выбрать фильтр с помощью jquery-фильтров.