views:

98

answers:

1

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'}))
+1  A: 

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.

Daniel Roseman
That's really clear. Once again ... thanks for your help Daniel.
alj