Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class FilterForm(FilterFormBase):
- """
- Form with filters in catalog
- """
- def __init__(self, items, category=None, *args, **kwargs):
- super(FilterForm, self).__init__(items, *args, **kwargs)
- # add brands field
- self._add_brands_field(items)
- # add category specific fields
- if category:
- self._add_category_fields(category, items)
- def _add_brands_field(self, items):
- # brands multiple checkboxes
- brands = items.values_list('brand', 'brand__name').order_by('brand__position').distinct()
- self.fields['brands'] = forms.MultipleChoiceField(choices=brands, widget=forms.CheckboxSelectMultiple(),
- label=_(u'Brands'), required=False)
- def _add_category_fields(self, category, items):
- # category specific fields
- parameters = category.parameters.all()
- def get_choices(parameter, field='value_str'):
- return ItemParameterMembership.objects.filter(item__in=items, parameter=parameter).values_list(
- field, field).order_by(field).distinct()
- for parameter in parameters:
- if parameter.widget == 'radio':
- field = forms.ChoiceField(choices=get_choices(parameter), widget=forms.RadioSelect(), required=False)
- elif parameter.widget == 'dimensions':
- choices = get_choices(parameter)
- if choices:
- # aggregate min and max dimensions
- width, length, height = set(), set(), set()
- for d in choices:
- ds = d[0].split('x')
- width.add(int(ds[0]))
- length.add(int(ds[1]))
- height.add(int(ds[2]))
- width, length, height = sorted(width), sorted(length), sorted(height)
- dimensions = [str(width[0]), str(width[-1:][0]), str(length[0]), str(length[-1:][0]),
- str(height[0]),
- str(height[-1:][0])]
- field = forms.CharField(widget=DimensionsWidget(dimensions), required=False)
- def wrapper(field_name):
- def clean_dimensions(self):
- """
- Dimensions field clean method
- """
- value = self[field_name].value()
- try:
- for i in value:
- int(i)
- except ValueError as e:
- raise ValidationError(self.error_messages['invalid_int'] + unicode(e))
- return clean_dimensions
- # monkey-patch the clean method for this field
- setattr(self, 'clean_' + parameter.input_name, types.MethodType(wrapper(parameter.input_name), self))
- else:
- field = None
- elif parameter.widget == 'range':
- choices = get_choices(parameter, 'value_int')
- if choices:
- field = forms.CharField(widget=RangeWidget(
- (choices[0][0], choices[len(choices) - 1][0]),
- attrs={
- 'class': 'price'
- }
- ), required=False)
- field_name = parameter.input_name
- def clean_range(self):
- """
- Range field clean method
- """
- value = self[field_name].value()
- try:
- Decimal(value[0])
- Decimal(value[1])
- except DecimalException:
- raise ValidationError(self.error_messages['invalid_decimal'])
- if value[0] > value[1] or (value[0] < 0 or value[1] < 0):
- raise ValidationError(self.error_messages['invalid_range'], code='invalid')
- # monkey-patch the clean method for this field
- setattr(self, 'clean_' + parameter.input_name, types.MethodType(clean_range, self))
- else:
- field = None
- else:
- # if 'checkbox' or any other
- field = forms.MultipleChoiceField(choices=get_choices(parameter), widget=forms.CheckboxSelectMultiple(),
- required=False)
- if field:
- field.label = parameter.name
- self.fields[parameter.input_name] = field
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement