没有一个答案实际上完全符合 clime 的要求。所以这是我对同样问题的解决方案:
class LeadsFiltersForm(forms.Form):
TYPE_CHOICES = Lead.TYPES
SITE_CHOICES = [(site.id, site.name) for site in Site.objects.all()]
type = forms.MultipleChoiceField(
choices=TYPE_CHOICES, widget=forms.CheckboxSelectMultiple(),
required=False
)
site = forms.MultipleChoiceField(
widget=forms.CheckboxSelectMultiple(), required=False,
choices=SITE_CHOICES
)
date_from = forms.DateField(input_formats=['%m-%d-%Y',], required=False,
widget=forms.TextInput(attrs={'placeholder': 'Date From'}),
initial=timezone.now() - datetime.timedelta(days=30))
date_to = forms.DateField(input_formats=['%m-%d-%Y',], required=False,
widget=forms.TextInput(attrs={'placeholder': 'Date To'}))
defaults = {
'type': [val[0] for val in TYPE_CHOICES],
'site': [val[0] for val in SITE_CHOICES],
'date_from': (timezone.now() - datetime.timedelta(days=30)).strftime('%m-%d-%Y'),
'date_to': timezone.now().strftime('%m-%d-%Y')
}
def __init__(self, data, *args, **kwargs):
super(LeadsFiltersForm, self).__init__(data, *args, **kwargs)
self.data = self.defaults.copy()
for key, val in data.iteritems():
if not data.get(key):
continue
field = self.fields.get(key)
if field and getattr(field.widget, 'allow_multiple_selected', False):
self.data[key] = data.getlist(key)
else:
self.data[key] = data.get(key)