You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

forms.py 2.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. from django import forms
  2. class FormFactory(object):
  3. u"""Factory for creating the "add-to-basket" forms."""
  4. def create(self, item, values=None):
  5. u"""For dynamically creating add-to-basket forms for a given product"""
  6. self.fields = {'action': forms.CharField(widget=forms.HiddenInput(), initial='add'),
  7. 'product_id': forms.IntegerField(widget=forms.HiddenInput(), min_value=1),
  8. 'quantity': forms.IntegerField(min_value=1)}
  9. self.values = values
  10. if not self.values:
  11. self.values = {'action': 'add',
  12. 'product_id': item.id,
  13. 'quantity': 1}
  14. if item.is_group:
  15. self._create_group_product_fields(item)
  16. else:
  17. self._create_product_fields(item)
  18. # See http://www.b-list.org/weblog/2008/nov/09/dynamic-forms/ for
  19. # advice on how this works.
  20. form_class = type('AddToBasketForm', (forms.BaseForm,), {'base_fields': self.fields})
  21. return form_class(self.values)
  22. def _create_group_product_fields(self, item):
  23. u"""
  24. Adds the fields for a "group"-type product (eg, a parent product with a
  25. list of variants.
  26. """
  27. choices = []
  28. for variant in item.variants.all():
  29. if variant.has_stockrecord:
  30. summary = u"%s (%s) - %.2f" % (variant.get_title(), variant.attribute_summary(),
  31. variant.stockrecord.price_incl_tax)
  32. choices.append((variant.id, summary))
  33. self.fields['product_id'] = forms.ChoiceField(choices=tuple(choices))
  34. def _create_product_fields(self, item):
  35. u"""Add the product option fields."""
  36. for option in item.options:
  37. self._add_option_field(item, option)
  38. def _add_option_field(self, item, option):
  39. u"""
  40. Creates the appropriate form field for the product option.
  41. This is designed to be overridden so that specific widgets can be used for
  42. certain types of options.
  43. """
  44. self.fields[option.code] = forms.CharField()