Django Поле множественного выбора / флажок Выбрать несколько - PullRequest
34 голосов
/ 28 апреля 2010

У меня есть приложение Django, и я хочу отобразить несколько вариантов в профиле пользователя. Затем они смогут выбрать несколько предметов.

Это упрощенная версия моих моделей.

from profiles.choices import SAMPLE_CHOICES

class Profile(models.Model):
    user = models.ForeignKey(User, unique=True, verbose_name_('user'))
    choice_field = models.CharField(_('Some choices...'), choices=SAMPLE_CHOICES, max_length=50)

И мой класс формы:

class ProfileForm(forms.ModelForm):
    choice_field = forms.MultipleChoiceField(choices=SAMPLE_CHOICES, widget=forms.CheckboxSelectMultiple)

    class Meta:
        model = Profile

И мои views.py:

if request.method == "POST":
    profile_form = form_class(request.POST, instance=profile)
    if profile_form.is_valid():
        ...
        profile.save()
return render_to_response(template_name, {"profile_form": profile_form,}, context_instance=RequestContext(request))

Я вижу, что POST отправляет только одно значение:

choice_field u'choice_three' 

И местный vars params отправляет список:

[u'choice_one', u'choice_two', u'choice_three']

Все поля формы отображаются правильно, но когда я отправляю POST, я получаю сообщение об ошибке

Ошибка привязки параметра 7 - возможно, неподдерживаемый тип.

Нужно ли обрабатывать поле множественного выбора дальше в представлении? Правильный ли тип поля модели? Любая помощь или ссылки будут с благодарностью.

Ответы [ 4 ]

34 голосов
/ 28 апреля 2010

Выбор профиля должен быть настроен как ManyToManyField для правильной работы.

Итак ... ваша модель должна выглядеть следующим образом:

class Choices(models.Model):
  description = models.CharField(max_length=300)

class Profile(models.Model):
  user = models.ForeignKey(User, blank=True, unique=True, verbose_name='user')
  choices = models.ManyToManyField(Choices)

Затем синхронизируйте базу данныхи загрузите варианты с различными доступными опциями.

Теперь ModelForm создаст себя ...

class ProfileForm(forms.ModelForm):
  Meta:
    model = Profile
    exclude = ['user']

И, наконец, представление:

if request.method=='POST':
  form = ProfileForm(request.POST)
  if form.is_valid():
    profile = form.save(commit=False)
    profile.user = request.user
    profile.save()
else:
  form = ProfileForm()

return render_to_response(template_name, {"profile_form": form}, context_instance=RequestContext(request))

Следует отметить, что вы можете настроить профиль несколькими способами, включая наследование.Тем не менее, это должно работать и для вас.

Удачи.

14 голосов
/ 29 апреля 2010

Решение Бранта абсолютно правильно, но мне нужно было изменить его, чтобы оно работало с несколькими флажками выбора и commit=false. Вот мое решение:

models.py

class Choices(models.Model):
    description = models.CharField(max_length=300)

class Profile(models.Model):
   user = models.ForeignKey(User, blank=True, unique=True, verbose_name_('user'))
   the_choices = models.ManyToManyField(Choices)

forms.py

class ProfileForm(forms.ModelForm):
    the_choices = forms.ModelMultipleChoiceField(queryset=Choices.objects.all(), required=False, widget=forms.CheckboxSelectMultiple)

    class Meta:
        model = Profile
        exclude = ['user']

views.py

if request.method=='POST':
    form = ProfileForm(request.POST)
    if form.is_valid():
        profile = form.save(commit=False)
        profile.user = request.user
        profile.save()
        form.save_m2m() # needed since using commit=False
    else:
        form = ProfileForm()

return render_to_response(template_name, {"profile_form": form}, context_instance=RequestContext(request))
13 голосов
/ 27 октября 2010

models.CharField является представлением CharField одного из вариантов. То, что вы хотите, это набор вариантов. Кажется, это не реализовано в django (пока).

Вы могли бы использовать для этого поле «многие ко многим», но это имеет тот недостаток, что выбор должен быть помещен в базу данных. Если вы хотите использовать жестко закодированные варианты, это, вероятно, не то, что вам нужно.

Есть фрагмент django на http://djangosnippets.org/snippets/1200/, который действительно , кажется, решает вашу проблему, реализуя ModelField MultipleChoiceField.

2 голосов
/ 09 июня 2016

ManyToManyField не является хорошим выбором. Вы можете использовать некоторые фрагменты для реализации MultipleChoiceField . Вас может вдохновить MultiSelectField со значениями, разделенными запятой (Field + FormField) Но в нем есть какая-то ошибка. И вы можете установить django-multiselectfield . Это более префект.

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