I ve a weird issue with a MultipleChoiceField that does not return the items that are in the POST QueryDict
here is the Form
class TranslationLanguagesForm(forms.Form):
languages = forms.MultipleChoiceField(
widget=forms.SelectMultiple(attrs={"novalidate": "",}),
choices=languages,
required=False,
)
the View is something like (shortened):
class AjaxSpotlerCreateView(View):
def post(self,request):
# ...
# some code before
#
translation_form = TranslationLanguagesForm(
self.request.POST, prefix="translation"
)
if translation_form.is_valid():
translation_languages = translation_form.cleaned_data.get(
"languages"
)
#
# some code after
#
I won't write the whole template but the html created by the form fits what I expected:
<select name="translation-languages" novalidate="" class="form-control " id="id_translation-languages" multiple="">
<option value="fr">french</option>
<option value="en">english</option> <option value="es">spanish</option> </select>
The jquery that sends the data trough ajax request is given below:
function ajaxPOST() {
var dismiss = false;
$.ajax({
method: "POST",
url: ajaxURL,
data: getFormData(),
beforeSend: function () {},
success: function (data) {
$target.find(".modal-content").html(data);
if (data.length == 0) dismiss = true;
},
complete: function () {
if (dismiss) hideUploadModal();
else showUploadModal();
}, //complete
}); //ajax
}
function getFormData() {
const result = {};
const $form = $target.find("form#video-loader-form");
const $inputs = $form.find("input, select, textarea");
$inputs.each((_, element) => {
const $element = $(element);
const type = $element.attr("type");
const name = $element.attr("name");
if (name && type == "checkbox" && $element.prop("checked"))
result[name] = $element.prop("checked");
else if (name && type != "checkbox") result[name] = $element.val();
});
return result;
}
the issue is that the form is never "filled" by the data of request.POST and translation_languages receives always an empty list.
...but self.request.POST.getlist("translation-languages[]")
returns the correct values
It only happened on MultipleChoiceField whereas ChoiceField returns the correct value
here are the POST data (you see more data than needed by the form with the issue because there are 4 forms and 1 formset in the view) :
<QueryDict: {'csrfmiddlewaretoken': ['bQQzHTR4JDFZFnmO1ExlPZhqURHswXTmXA9RGC2c05pBM63ns2gnVwUnbnwGzor1'], 'transcription-language': ['en-us'], 'translation-languages[]': ['fr', 'es'], 'spotlers-TOTAL_FORMS': ['1'], 'spotlers-INITIAL_FORMS': ['1'], 'spotlers-MIN_NUM_FORMS': ['0'], 'spotlers-MAX_NUM_FORMS': ['1000'], 'spotlers-0-url': ['https://test-dev-s.storage.googleapis.com/uploads/FR/5e24512/2021/1/9fccac26/9fc37a26-2545-434f-8bd2-0afc3df839aa_full.mp4?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=storage%40funky-tower-264412.iam.gserviceaccount.com%2F20210108%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20210108T125533Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host&x-goog-signature=8e737cbc384fab5e11002cbc5e6308'], 'spotlers-0-id': ['9fc37a26-1893-434f-8bd2-0afc3df839ef'], 'spotlers-0-name': ['ultraclimb'], 'spotlers-0-duration': ['00:02:43'], 'spotlers-0-is_postedited': ['true'], 'keywords-keywords': [''], 'glossary-glossary': ['']}>
It seems also that the dict returned by ajax POST creates a weird name for multiselect. The name of the field is postfixed by array symbols : []...
So I got 'translation-languages[]': ['fr', 'es']
instead of having 'translation-languages': ['fr', 'es']