23

I have the following code:

category = forms.ModelMultipleChoiceField(
    label="Category",
    queryset=Category.objects.order_by('name'),
    widget=forms.Select(
        attrs={
            'placeholder': 'Product Category', 'class': 'form-control'}),
    required=True
)

how do I set an initial value in the select box like "Choose a category" so that the select box should have a list of categories with the initial value being "Choose a category"

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
Chris Hansen
  • 7,813
  • 15
  • 81
  • 165
  • You can use [`empty_label`](https://docs.djangoproject.com/en/dev/ref/forms/fields/#django.forms.ModelChoiceField.empty_label) attribute – MHeidarian Dec 29 '18 at 06:17

4 Answers4

20

You can pass it the "initial" setting from your view. For example:

form = FormUsingCategory(initial={'category':querysetofinitialvalues})

The tricky part is that you must have the right queryset. Just like the seed values, it must be of Category.objects.filter(...) - anything else won't work.

bethlakshmi
  • 4,581
  • 22
  • 44
  • This is the only thing I could find online that actually works. +1 – Daniel Oct 17 '16 at 05:51
  • thankyou for the tip about getting the right queryset... I had been trying to prepopulate modelmultiplechoicefield by overriding get_initial(), but the values never appeared because the supplied queryset was for the wrong model. – mmw Jan 21 '19 at 17:40
  • I cannot confirm this on Django 3.2.5, passing a queryset does not work, it has to be a list, as outlined in other answers – Werner Trelawney Jul 13 '22 at 15:58
15

If you pass a QuerySet object as an initial value and if widget=forms.CheckboxSelectMultiple, then the check boxes are not checked. I had to convert the QuerySet object to a list, and then the check boxes were checked:

YourForm(
    initial={
        "multi_field": [
            cat for cat in Category.objects.all().values_list("id", flat=True)
        ]
    }
)
user2233706
  • 6,148
  • 5
  • 44
  • 86
13

Either set initial when you create form instance or set field initial in form init

def __init__(self, *args, **kwargs):
    super(YourForm, self).__init__(*args, **kwargs)
    self.fields["category"].initial = (
        Category.objects.all().values_list(
            'id', flat=True
        )
    )

If you just want to change the text when no field selected you can set empty_label property. https://docs.djangoproject.com/en/1.10/ref/forms/fields/#django.forms.ModelChoiceField.empty_label

James
  • 13,571
  • 6
  • 61
  • 83
0

I needed something similar in admin and in ModelForm i just did something like:

    def __init__(self, *args, **kwargs):
        super(CategoryAdminForm, self).__init__(*args, **kwargs)
        self.initial['category'] = list(Category.objects.filter(name=<whatever_you_need>))

and it worked fine for me

Gedrex ..
  • 11
  • 4