Формы django дают: Выберите правильный выбор. Этот выбор не является одним из доступных вариантов

Я не могу поймать значения из unit_id после того, как выбор сделан пользователем, и данные опубликованы. Может кто-то помочь мне решить эту проблему.

Значения раскрывающегося списка unit_id получены из другой таблицы базы данных (LiveDataFeed). И как только значение выбрано и форма отправлена, это дает ошибку:

Выберите допустимый выбор. Этот выбор не является одним из доступных вариантов.

Вот реализация:

в models.py:

class CommandData(models.Model):
    unit_id = models.CharField(max_length=50)
    command = models.CharField(max_length=50)
    communication_via = models.CharField(max_length=50)
    datetime = models.DateTimeField()
    status = models.CharField(max_length=50, choices=COMMAND_STATUS)  

В views.py:

class CommandSubmitForm(ModelForm):
    iquery = LiveDataFeed.objects.values_list('unit_id', flat=True).distinct()
    unit_id = forms.ModelChoiceField(queryset=iquery, empty_label='None',
        required=False, widget=forms.Select())

class Meta:
    model = CommandData
    fields = ('unit_id', 'command', 'communication_via')

def CommandSubmit(request):
    if request.method == 'POST':
        form = CommandSubmitForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponsRedirect('/')
    else:
        form = CommandSubmitForm()

    return render_to_response('command_send.html', {'form': form},
        context_instance=RequestContext(request))

Ответ 1

Вы получаете плоскую таблицу value_list, которая будет просто списком идентификаторов, но когда вы это сделаете, вам, вероятно, лучше использовать простой ChoiceField вместо ModelChoiceField и предоставить ему список кортежей, а не только идентификаторы. Например:

class CommandSubmitForm(ModelForm):
    iquery = LiveDataFeed.objects.values_list('unit_id', flat=True).distinct()
    iquery_choices = [('', 'None')] + [(id, id) for id in iquery]
    unit_id = forms.ChoiceField(iquery_choices,
                                required=False, widget=forms.Select())

Вы также можете оставить его как ModelChoiceField и использовать LiveDataFeed.objects.all() в качестве набора запросов, но чтобы отобразить идентификатор в поле, а также заполнить его значениями, вам придется подклассы ModelChoiceField, чтобы переопределить метод label_from_instance. Вы можете увидеть пример в документах здесь.

Ответ 2

Перед вызовом form.is_valid() выполните следующие действия:

  • unit_id = request.POST.get('unit_id')

  • form.fields['unit_id'].choices = [(unit_id, unit_id)]

Теперь вы можете позвонить form.is_valid(), и ваша форма будет правильно проверена.