Basically, I need to create a form (an inline formset actually), that contains 1 input field (a %) with an associated label/description (to help user), as well as some foreign keys. How many times, and what the description should be for each input field depends on another table. Some models.py pseudo-code to give an idea:
class MetaGroup(Model) description = CharField(....) < other irrelevant fields > class Discounts(Model) fk_metagroup = ForeignKey(MetaGroup, ...) fk_client = ForeignKey(Client, ....) percentage = Decimal(....)
The CONTENT of the
MetaGroup table is what determines the things on which discounts could be applied. So basically, an discount entry is related to a specific client (
fk_client) and to a specific MetaGroup (
fk_metagroup). The description comes from
fk_metagroup.description, and then the % determines what the discount is for that client with items from that MetaGroup. That all gets saved in the Discounts table, which is basically a list of all the discounts for on all the metagroups for all the clients. (I know this isn’t a very good structure to store that information, but that’s the way it’s been built and we’re not refactoring that now, so…)
For instance, the content of MetaGroup would look like:
In which case, my
DiscountsForm would display 3 rows, with Plastic cable, Led Lights, Actuator in the 1st column, and the input fields would be 1 decimal fields for each (the applicable discount on each of those group). In a separate form, the user can create a new group (say, pk=4, Description=Halogene Lights). In that case, my Discounts forms would need to offer another row for the new MetaGroup “Halogene Lights”, etc. The Discount formset actually appears within the
ClientForm as an
inline_formset of the
ClientForm, so setting the
fk_client is straightforward. I will have to manually set the
fk_metagroup manually when saving the form however.
I’m not sure what the best way to go about this is. Currently thinking something like:
class DiscountsForm(ModelForm): class Meta: model = Discount fields = ["percentage"] DiscountFormset = inlineformset_factory(Client, Discount, form=DiscountForm, extra=1, can_delete=False)
However… a few issues:
extra=… isn’t a set number. I guess I could set it to some callback function (e.g.
def how_many_discounts():defined above in forms.py, checking with the MetaGroup how many forms needs to be in the formset.
I will need to put the associated descriptions (and the associated
metagroup.pkso I can set
fk_metagroupwhen saving each
DiscountForminstance) in the context for the template to build the table to display to the user somehow. I’m thinking an inclusion_tag could do that. But then I’m somewhat spreading out the logic for how that form works. Can I add a method to my
DiscountFormclass and call that from the template to manage this?
Assume I get, say 4 discounts groups as per example above, along with 4 input fields from my
DiscountsForm, then I would iterate on that in the template with a for loop, building my table. When the user saves the Client form, I will have to manage adding
fk_metagroup to each new Discount instance (overriding
save() or something like that the view… using a CreateView/Edit).
Any better ideas? Things I’m not seeing?