1
class form(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        u = User.objects.get(user=user)
        super(form, self).__init__(*args, **kwargs)

        self.fields['phone'].queryset = Phone.objects.filter(user=u)

    class Meta:
        model = MyModel
        fields = ["name", "description", , "phone"]

This form pre-populates the field phones with phones that belong to the currently logged in user. I got the template to display using {{ form.as_p }}, but I dont know how to manually display the fields with the pre-populated phone names to be chosen, in an html template.

I tried the snippet below as part of the bigger form, but it did not work.

<select multiple="multiple" id="id_phone" name="phone" required>
            {% for p in phone %}
            <option value="{{ p.id }}">{{ p.name }}</option>
            {% endfor %}
</select>

Also, how can I allow a user to choose multiple phones at once with this pre-population method. I tried to use ModelMultipleChoiceField but it did not work.

thatguy
  • 97
  • 9
  • Why do you need to show it manually? What sort of a field is this? And what "didn't work" when you tried to use ModelMultipleChoiceField? – Daniel Roseman Jun 22 '17 at 20:48
  • I want to do it manually so that I can give classes to each input and label and be able to do the design the form anyway I want. It is a select field, it has options and the user chooses which phone they want added. When I tried to use ModelMultipleChoiceField, I just could not figure out how to pass in the queryset from self.fields['phone'].queryset – thatguy Jun 22 '17 at 20:52

1 Answers1

0

There are two things that you need in this situation

  1. Set an initial value for the field
  2. Set the field widget to be able to select multiple values

Luckily, Django already has a widget for that!

The following code will achieve what you want:

class form(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        u = User.objects.get(user=user)
        kwargs["initial"].update({
            "phone": Phone.objects.filter(user=u)
        })
        super(form, self).__init__(*args, **kwargs)

    class Meta:
        model = MyModel
        widgets = {
            "phone": SelectMultiple
        }
        fields = ["name", "description", "phone"]

With these two pieces in place, the template becomes easy!

{{ form.phone.errors }}  {# shows on page any errors during clean #}
{{ form.phone }}         {# renders the widget #}

If you do not want to use the built in widget that Django provides, look into creating your own

For other ways to set initial values checkout this post