Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add additional options to Django form select widget

Tags:

I have a form which I use to construct a queryeset filter. The form pulls in the project status options from the database. However, I wanted to add additional options, for example "All live promotions" ... so the select box would then look something like:

  • All Promotions *
  • All Live Promotions *
  • Draft
  • Submitted
  • Accepted
  • Reported
  • Checked
  • All Completed Promotions *
  • Closed
  • Canceled

Here the '*' are the ones I'd want to add and the others come from the database.

Is this possible?

class PromotionListFilterForm(forms.Form):
    promotion_type = forms.ModelChoiceField(label="Promotion Type", queryset=models.PromotionType.objects.all(), widget=forms.Select(attrs={'class':'selector'}))
    status = forms.ModelChoiceField(label="Status", queryset=models.WorkflowStatus.objects.all(), widget=forms.Select(attrs={'class':'selector'})) 
    ...
    retailer = forms.CharField(label="Retailer",widget=forms.TextInput(attrs={'class':'textbox'}))
like image 770
alj Avatar asked Sep 13 '10 12:09

alj


1 Answers

You won't be able to use a ModelChoiceField for that. You'll need to revert to a standard ChoiceField, and create the options list manually in the form's __init__ method. Something like:

class PromotionListFilterForm(forms.Form):
    promotion_type = forms.ChoiceField(label="Promotion Type", choices=(),
                                       widget=forms.Select(attrs={'class':'selector'}))
    ....

    EXTRA_CHOICES = [
       ('AP', 'All Promotions'),
       ('LP', 'Live Promotions'),
       ('CP', 'Completed Promotions'),
    ]

    def __init__(self, *args, **kwargs):
        super(PromotionListFilterForm, self).__init__(*args, **kwargs)
        choices = [(pt.id, unicode(pt)) for pt in PromotionType.objects.all()]
        choices.extend(EXTRA_CHOICES)
        self.fields['promotion_type'].choices = choices

You'll also need to do something clever in the form's clean() method to catch those extra options and deal with them appropriately.

like image 149
Daniel Roseman Avatar answered Nov 14 '22 21:11

Daniel Roseman