Handling multiple related objects in the admin without using inlines
I am customising Django's admin for a particular view on some data.
Where I have got so far
I have a Project
model, and a ProjectObjectConditions
model that has a ForeignKey to it (the actual models (on Github)):
class Project(models.Model):
[...]
class ProjectObjectiveCondition(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
With a custom inline admin template (on Github), the inlines look like this:
What you are seeing there is:
Objective
: AgreeablenessLevel
: StartedCondition
: Speaks pleasantlyCondition
: Doesn't shout
Level
: First resultsCondition
: Accepts thanks with gracce
Level
: Mature resultsCondition
: Apologises with sincerity
Objective
: ColourfulnessLevel
: StartedCondition
: Has blue- ... and so on
The Conditions
are grouped by Objective
and Level
through repeated use of {% regroup %}
in the template.
Date/commitment columns
You can also see columns for the dates (instances of the WorkCycle
class) and their True
/False
values, that show whether a commitment was made for this Project, and to reach which Level
, in which WorkCycle
(i.e. in which year).
I want to replace those with editable tick-boxes.
I actually have another inline, LevelCommitmentInline
, which allows me to edit those True
/False
values for that model - but I don't want them in a long list somewhere else, I want to see each one against the Objective
and Level
it is associated with, and under the date columns - right here.
How to do it
I think I will need to generate multiple forms to do this, one for each Objective
/Level
of the Project
, for each WorkCycle
. And then I will need to find a way to attach each of those forms to something - but I don't know what.
The Objective
and Level
objects in this template, which those additional forms will need to be associated with in the admin page, don't actually come from this form, they are extracted by using {% regroup %}
, i.e.
# regroup the inline_admin_formset
{% regroup inline_admin_formset by form.instance.projectobjective as objective_list %}
# loop over the new list
{% for objective_formset in objective_list %}
# get the Objective attributes I need from the formset
{{ objective_formset.grouper.objective.description }}
Then the same again in order to get hold of `LevelCommitment` objects and their fields.
Any bright ideas?