Factors _QuantityBoxForm out of _ProductsForm

This commit is contained in:
Christopher Neugebauer 2016-03-27 10:23:59 +11:00
parent 834233cd72
commit 0ae005a5f5

View file

@ -3,51 +3,83 @@ import models as rego
from django import forms
# Products forms -- none of these have any fields: they are to be subclassed
# and the fields added as needs be.
class _ProductsForm(forms.Form):
PRODUCT_PREFIX = "product_"
''' Base class for product entry forms. '''
def __init__(self, *a, **k):
if "product_quantities" in k:
initial = self.initial_data(k["product_quantities"])
k["initial"] = initial
del k["product_quantities"]
super(_ProductsForm, self).__init__(*a, **k)
@classmethod
def field_name(cls, product):
return cls.PRODUCT_PREFIX + ("%d" % product.id)
@classmethod
def set_fields(cls, products):
''' Sets the base_fields on this _ProductsForm to allow selecting
from the provided products. '''
pass
@classmethod
def initial_data(cls, product_quantites):
''' Prepares initial data for an instance of this form.
product_quantities is a sequence of (product,quantity) tuples '''
return {}
def product_quantities(self):
''' Yields a sequence of (product, quantity) tuples from the
cleaned form data. '''
return iter([])
class _QuantityBoxProductsForm(_ProductsForm):
''' Products entry form that allows users to enter quantities
of desired products. '''
@classmethod
def set_fields(cls, products):
for product in products:
help_text = "$%d -- %s" % (product.price, product.description)
field = forms.IntegerField(
label=product.name,
help_text=help_text,
)
cls.base_fields[cls.field_name(product)] = field
@classmethod
def initial_data(cls, product_quantities):
initial = {}
for product, quantity in product_quantities:
initial[cls.field_name(product)] = quantity
return initial
def product_quantities(self):
for name, value in self.cleaned_data.items():
if name.startswith(self.PRODUCT_PREFIX):
product_id = int(name[len(self.PRODUCT_PREFIX):])
yield (product_id, value, name)
def ProductsForm(products):
''' Produces an appropriate _ProductsForm subclass for the given render
type. '''
PREFIX = "product_"
if True:
class ProductsForm(_QuantityBoxProductsForm):
pass
def field_name(product):
return PREFIX + ("%d" % product.id)
class _ProductsForm(forms.Form):
def __init__(self, *a, **k):
if "product_quantities" in k:
initial = _ProductsForm.initial_data(k["product_quantities"])
k["initial"] = initial
del k["product_quantities"]
super(_ProductsForm, self).__init__(*a, **k)
@classmethod
def initial_data(cls, product_quantities):
''' Prepares initial data for an instance of this form.
product_quantities is a sequence of (product,quantity) tuples '''
initial = {}
for product, quantity in product_quantities:
initial[field_name(product)] = quantity
return initial
def product_quantities(self):
''' Yields a sequence of (product, quantity) tuples from the
cleaned form data. '''
for name, value in self.cleaned_data.items():
if name.startswith(PREFIX):
product_id = int(name[len(PREFIX):])
yield (product_id, value, name)
for product in products:
help_text = "$%d -- %s" % (product.price, product.description)
field = forms.IntegerField(
label=product.name,
help_text=help_text,
)
_ProductsForm.base_fields[field_name(product)] = field
return _ProductsForm
ProductsForm.set_fields(products)
return ProductsForm
class ProfileForm(forms.ModelForm):