Advertisement
mennanov

Untitled

Jul 16th, 2014
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.76 KB | None | 0 0
  1. class FilterForm(FilterFormBase):
  2.     """
  3.    Form with filters in catalog
  4.    """
  5.  
  6.     def __init__(self, items, category=None, *args, **kwargs):
  7.         super(FilterForm, self).__init__(items, *args, **kwargs)
  8.  
  9.         # add brands field
  10.         self._add_brands_field(items)
  11.         # add category specific fields
  12.         if category:
  13.             self._add_category_fields(category, items)
  14.  
  15.     def _add_brands_field(self, items):
  16.         # brands multiple checkboxes
  17.         brands = items.values_list('brand', 'brand__name').order_by('brand__position').distinct()
  18.         self.fields['brands'] = forms.MultipleChoiceField(choices=brands, widget=forms.CheckboxSelectMultiple(),
  19.                                                           label=_(u'Brands'), required=False)
  20.  
  21.     def _add_category_fields(self, category, items):
  22.         # category specific fields
  23.         parameters = category.parameters.all()
  24.  
  25.         def get_choices(parameter, field='value_str'):
  26.             return ItemParameterMembership.objects.filter(item__in=items, parameter=parameter).values_list(
  27.                 field, field).order_by(field).distinct()
  28.  
  29.         for parameter in parameters:
  30.  
  31.             if parameter.widget == 'radio':
  32.                 field = forms.ChoiceField(choices=get_choices(parameter), widget=forms.RadioSelect(), required=False)
  33.             elif parameter.widget == 'dimensions':
  34.                 choices = get_choices(parameter)
  35.                 if choices:
  36.                     # aggregate min and max dimensions
  37.                     width, length, height = set(), set(), set()
  38.                     for d in choices:
  39.                         ds = d[0].split('x')
  40.                         width.add(int(ds[0]))
  41.                         length.add(int(ds[1]))
  42.                         height.add(int(ds[2]))
  43.                     width, length, height = sorted(width), sorted(length), sorted(height)
  44.                     dimensions = [str(width[0]), str(width[-1:][0]), str(length[0]), str(length[-1:][0]),
  45.                                   str(height[0]),
  46.                                   str(height[-1:][0])]
  47.                     field = forms.CharField(widget=DimensionsWidget(dimensions), required=False)
  48.  
  49.                     def wrapper(field_name):
  50.  
  51.                         def clean_dimensions(self):
  52.                             """
  53.                            Dimensions field clean method
  54.                            """
  55.                             value = self[field_name].value()
  56.                             try:
  57.                                 for i in value:
  58.                                     int(i)
  59.                             except ValueError as e:
  60.                                 raise ValidationError(self.error_messages['invalid_int'] + unicode(e))
  61.                         return clean_dimensions
  62.  
  63.                     # monkey-patch the clean method for this field
  64.                     setattr(self, 'clean_' + parameter.input_name, types.MethodType(wrapper(parameter.input_name), self))
  65.                 else:
  66.                     field = None
  67.             elif parameter.widget == 'range':
  68.                 choices = get_choices(parameter, 'value_int')
  69.                 if choices:
  70.                     field = forms.CharField(widget=RangeWidget(
  71.                         (choices[0][0], choices[len(choices) - 1][0]),
  72.                         attrs={
  73.                             'class': 'price'
  74.                         }
  75.                     ), required=False)
  76.                     field_name = parameter.input_name
  77.  
  78.                     def clean_range(self):
  79.                         """
  80.                        Range field clean method
  81.                        """
  82.                         value = self[field_name].value()
  83.                         try:
  84.                             Decimal(value[0])
  85.                             Decimal(value[1])
  86.                         except DecimalException:
  87.                             raise ValidationError(self.error_messages['invalid_decimal'])
  88.                         if value[0] > value[1] or (value[0] < 0 or value[1] < 0):
  89.                             raise ValidationError(self.error_messages['invalid_range'], code='invalid')
  90.  
  91.                     # monkey-patch the clean method for this field
  92.                     setattr(self, 'clean_' + parameter.input_name, types.MethodType(clean_range, self))
  93.                 else:
  94.                     field = None
  95.             else:
  96.                 # if 'checkbox' or any other
  97.                 field = forms.MultipleChoiceField(choices=get_choices(parameter), widget=forms.CheckboxSelectMultiple(),
  98.                                                   required=False)
  99.             if field:
  100.                 field.label = parameter.name
  101.                 self.fields[parameter.input_name] = field
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement