Alternate widgets and logic for ManyToManyField with Django forms
- by Jaearess
In my Django project, I have a simple ticket system. When creating a ticket, certain users have the ability to assign the ticket to other users, and to email the ticket to other users as well (this is used as an FYI for those users, so they're aware of the ticket, even though it's not assigned to them.)
At the moment, the form for adding a ticket is simply the default Django form, with the "assigned_to" and "email_to" fields being ManyToManyFields, and therefore displayed as MultipleSelect widgets, each with a list of all users. Due to the relatively large number of users, and general awkwardness of the MultipleSelect widget, and alternate layout is now required.
The desired layout is a pair of simple Select widgets side-by-side. The first has the option of "Assign to" or "Email to" and the second is a list of the users. Essentially, like this:
[Assign to] [John Doe]
[Email to] [Jane Roe]
[Jack Smith], etc.
Of course, since an arbitrary number of users can be assigned or emailed a ticket, there's a simple button that runs some Javascript to add another set of widgets, to allow the user to assign and email as many people as they need to.
So far all of that is fairly simple and straight forward. However, the problem I have is using this widget setup/logic setup with Django forms. Instead of lists of users to assign to and email, instead we're getting back pairs of information, one a user and the other which list that user should be placed in.
What I'm looking for, but have yet to find, is a way to offload the translation between how the user uses the form, and how Django understands the model to the form itself, so I don't have to manually do the processing of the data before passing it to the form in each place this form is used.
Additionally, there's a review screen with the option to go back and change the form before submitting it, so a way to have the form translate both to and from this format would be extremely helpful.