I'm having a hard time figuring out how to update a Field in Django Form while editing the Form.
In my form I have a ModelChoiceField and ChoiceField: first is a list of Car manufacturers, second is a list of models available for this manufacturer. Obviously I don't want to fill second field with models for every manufacturer but only for one selected in first ModelChoiceField.
Here's my example Form:
class PostForm(forms.ModelForm): make = forms.ModelChoiceField(queryset=Manufacturer.objects.all()) model = forms.ChoiceField() ... To render the template with form I use Class-based View:
class CreatePost(View): template_name = 'post/edit_post.html' def get(self, request): form = PostForm() return render(request, self.template_name, {'form': form}) def post(self, request): form = PostForm(request.POST) if form.is_valid(): post = form.save(commit=False) post.owner = request.user post.save() return redirect('homepage') return render(request, self.template_name, {'form': form}) In my template after I render PostForm I disable model field with jQuery and wait for user to select some value in make field. Here's my template:
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.non_field_errors }} {% for field in form %} <div class="form-group"> <label class="control-label">{{ field.label_tag }}</label> {{ field }} {{ field.errors }} </div> <div class="form-group"> <button type="submit" class="btn btn-default">Submit</button> </div> {% endfor %} </form> And then use AJAX to request values for model field (in this sample code I only return single item):
$('#id_make').change(function () { $.ajax({ url: '{% url 'get_models' %}', data: {'make': $('#id_make :selected').text()}, dataType: 'json', success: function (data) { $('#id_model').append($('<option>', { value: 1, text: data.model})).removeAttr('disabled'); } }); }) Here's the view I'm using to process AJAX call (for display purposes and to keep things simple in this question I have only one record in models table Series for each manufacturer and knowing this I only query for one record. series is CharField that keeps title of model like 'Lancer' for 'Mitsubishi' manufacturer.):
def get_models(request): manufacturer = Manufacturer.objects.get(make=request.GET.get('make')) model = Series.objects.get(make_fk= manufacturer) return JsonResponse({'model': model.series}) With this done I do see updated options in <select> element for model ChoiceField, but after I select new value in model ChoiceField and submit form I receive:
Select a valid choice. 1 is not one of the available choices." - '1' is id of the element that I appended to
<select>element and then submit.
I then dug deeper and printed the contents of submitted Form and it appeared that although I saw <select> element updated in the template, it stayed blank in the Form I've submitted:
<select name="model" class="form-control" id="id_model"></select> Why is this happening and how to update Form fields itself rather than just <select> element?