dsalaj
dsalaj

Reputation: 3197

Django restrict options of ManyToMany field in ModelForm based on model instance

I want to show only options already stored in models' ManyToManyField. I have model Order which I want to have a Model based form like this:

class OrderForm(ModelForm):
    class Meta:
        model = Order
        fields = ['amount', 'color']

Now I do not want to display all colors as choices, but instead only color instances saved in ManyToManyField of another model. The other model is Design:

class Design(models.Model):
    color = models.ManyToManyField('maker.Color')
    # ...

Is this at all possible while using ModelForm?

Attempt

I have tried doing it by having a ModelForm of Design and setting instance:

class ColorForm(ModelForm):
    class Meta:
        model = Design
        fields = ['color']

And then in view:

color_form = ColorForm(instance=design)

But I don't exactly understand what setting instance does, and I think instance is not what I am looking for as it still lists all colors.

Upvotes: 2

Views: 748

Answers (1)

Wtower
Wtower

Reputation: 19902

The instance setting has nothing to do with limiting the choices. In essence, it simply populates the form's values with the ones from a specific record. You usually provide an instance in an edit operation, whereas you skip it in an add operation.

The representation of a models.ManyToManyField in the ModelForm is a forms.ChoiceField for which you can simply override its queryset property, and specify the queryset you desire.

Therefore, in your view:

form = OrderForm()
form.fields['color'].queryset = Design.object.all()  # for example

Upvotes: 2

Related Questions