Проверка на динамически установленном MultipleChoiceField, где поле изначально пусто? - PullRequest
2 голосов
/ 25 августа 2011

У меня есть представление с несколькими различными формами. Первая форма имеет поле поиска, которое заполняет поле с множественным выбором, и когда пользователь вводит свой запрос в поле поиска, отправляется вызов AJAX для получения всех записей, соответствующих запросу. Затем пользователь выбирает варианты из первого поля множественного выбора и нажимает «Добавить», чтобы переместить их в другое поле множественного выбора

Это работает нормально, но при отправке формы я получаю сообщение об ошибке: Msgstr "Выбрать правильный выбор. 1 не является одним из доступных вариантов." Я попытался установить варианты после получения аргументов в форме init, но это не похоже на работу.

Моя форма:

class SiteCoordinatorForm(forms.ModelForm):
    selected_studies = forms.MultipleChoiceField(required = False)
    site = forms.ChoiceField(required = False)    
    studies = forms.MultipleChoiceField(required = False)
    study_search = forms.CharField(max_length = 50, required = False)

    def __init__(self, *args, **kwargs):
        super(SiteCoordinatorForm, self).__init__(*args, **kwargs)        
        if args:
            study_list = []
            query_dict = args[0]
            self.fields['selected_studies'].choices = [(int(x), x) for x in   query_dict.getlist('selected_studies')]

        self.fields['site'].choices = [(x.pk, "%s (%s)" % (x.primary_name, x.primary_number)) for x in Site.objects.all().order_by('primary_name')]

    class Meta:
        model = SiteCoordinator
        exclude = ('studies', 'site', 'selected_studies')

Моя функция AJAX, которая заполняет поле:

def search_studies(request):
    return_data = {}
    studies = []
    make_query = lambda terms, fieldname: reduce(lambda x, y: x & Q(**{fieldname + '__icontains': y}), terms, Q())
    if 'search_text' in request.POST:
        terms = request.POST['search_text'].split()
        for rec in Study.objects.filter(make_query(terms, 'name')):
            studies.append({
                'study': {'id': rec.id, 'name': rec.name, 'number': rec.id}
            })

    response = {'status': 'success', 'count': len(studies), 'studies': studies}
    return HttpResponse(simplejson.dumps(response), mimetype="application/json")

Функция для заполнения MultiSelectBox:

function show_results(data, status_code, request){
    recs = data.studies;
    var select_box = document.getElementById('id_studies');
    select_box.options.length = 0;

    for (var index = 0; index < recs.length; index ++){
        select_box.options[index] = new Option(recs[index].study.name,
                        recs[index].study.id,
                        false, false);
    }
}

Затем JQuery для перемещения выбора:

$('#add').click(function() {
    $('#id_studies option:selected').remove().appendTo('#id_selected_studies');
    return false;

});

$('#remove').click(function() {  
    $('#id_selected_studies option:selected').remove().appendTo('#id_studies');
    return false;
});

Ответы [ 2 ]

4 голосов
/ 31 октября 2011

Ясно, что мы не хотим проверок MultipleChoiceField, но хотим MultipleSelectWidget, поэтому решение состоит в том, чтобы просто изменить поле на

studies = forms.CharField(widget=forms.SelectMultiple)

и выполнить ваши собственные проверки в

def clean_studies(self):
    ...
0 голосов
/ 26 ноября 2015

Вот пример, который использует решение, предложенное @AnuragUniyal, и который также отвечает на комментарий @ JohnLehmann:

class MyForm(forms.Form):
    new_tags = forms.CharField(required=False, widget=forms.SelectMultiple)

    def save(self, commit=True):
        instance = super(MyForm, self).save(commit=commit)
        for tag in eval(self.cleaned_data['new_tags']):
            models.Tag.objects.get_or_create(name=tag)
        return instance

В основном мы преобразуем строку списка строк Unicode обратно в список Python, применяя eval() на нем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...