django ModelMultipleChoiceField set initial values
Asked Answered
O

4

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"

Orcutt answered 17/11, 2014 at 6:7 Comment(1)
You can use empty_label attributeExportation
Z
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)
        ]
    }
)
Zerelda answered 12/10, 2017 at 15:19 Comment(2)
This is the answer that a lot of people will need. thanks!\Lonne
This worked for me, but could you please explain (or provide documentation reference) how this thing works? What is the loop performed here in cat for cat in objectsWaistband
F
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.

Fulcher answered 14/2, 2015 at 17:59 Comment(3)
This is the only thing I could find online that actually works. +1Oates
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.Tarnopol
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 answersGypsy
Z
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)
        ]
    }
)
Zerelda answered 12/10, 2017 at 15:19 Comment(2)
This is the answer that a lot of people will need. thanks!\Lonne
This worked for me, but could you please explain (or provide documentation reference) how this thing works? What is the loop performed here in cat for cat in objectsWaistband
Z
14

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

Zap answered 25/8, 2016 at 17:20 Comment(0)
B
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

Bogusz answered 26/6, 2022 at 0:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.