I have a form:
*# dialogues.forms*
class CreateConferenceForm(forms.Form):
...
participants = forms.MultipleChoiceField(choices=?)
...
And I need to put in choices argument instead of "?" data from friends field in this model:
*# persons.models*
class Person(User):
...
friends = models.ManyToManyField(
'self',
related_name='+',
)
...
How can I do it?
If you're creating an instance of a conference model with your form, you should consider using Django's ModelForm
, which is designed to be used in the creation and editing of model instances.
In either case, you can use a ModelMultipleChoiceField
to serve your purpose, which is simply a MultipleChoiceField
backed by a queryset for its choices. You can use this field in either a standard Form
or a ModelForm
.
To customize the choices based on the request, you can set the queryset in your view.
For example:
forms.py
class CreateConferenceForm(forms.Form):
# An initial queryset is required, this is overwritten in the view
participants = forms.ModelMultipleChoiceField(Person.objects.all())
views.py
def new_conference(request):
data = request.POST if request.method == 'POST' else None
conference_form = CreateConferenceForm(data=data)
conference_form.fields['participants'].queryset = my_person.friends.all()
if data:
if conference_form.is_valid():
# etc
return render...
Note that it is important for you to set the queryset prior to calling is_valid
on the form, since the queryset is used in validation, and prior to sending passing the form to a template, since the queryset is used to generate the choices shown.