Looking for help showing/editing a many-to-many relationship
I'm working on making a page that allows saving a few boolean values for the intersection of two different models. I think I need a many-to-many relation through a related model. Here's roughly what I have in that regard.
def A(models.Model):
name = models.CharField(max_length=200)
def B(models.Model):
rows = models.ManyToManyField('A', through='Row', through_fields=('my_B', 'my_A'))
def Row(models.Model)
my_B = models.ForeignKey(B, on_delete=models.CASCADE)
my_A = models.ForeignKey(A, on_delete=models.CASCADE)
col1 = models.BooleanField()
col2 = models.BooleanField()
col3 = models.BooleanField()
I believe that's roughly correct for what I'm trying to do (though I'm open to suggestions). However, I'm not sure how to get data into the database in a nice way. I want to make a page laid out something like this (with one such page for each B):
| B1 | Col 1 | Col 2 | Col3 |
|---|---|---|---|
| A1 | ☐ | ☒ | ☐ |
| A2 | ☒ | ☐ | ☐ |
| A3 | ☐ | ☐ | ☒ |
I'm looking for one page per element of B with all of the A elements as rows with checkboxes and a Submit button to save changes. The Columns are fixed, but the number of rows of A will vary. Not all As will need relations to all Bs, it's a somewhat sparse dataset; probably 60-80% of As has one or more True columns for any given B.
I'm looking for some help writing a view and template to both display the boolean values as checkboxes and then save modifications back to the database (adding Row elements when a previously all-False A gets at least one True value). Or, if someone knows of a better way to tackle this problem, I'm not at all tied to this approach.
Posted Jan 14, 2020, 3:18 PM UTC
Since you have an intermediary model to your m2m relationship, you will need to handle its saving manually.
With a formset_factory this should be fairly straightforward. Each line of your table will be a formset.
Then in your view :
Didn't test this code but I would go with this direction.
Thanks, that does appear to be along the lines of what I'm looking for. I think I'm still missing something though, since passing the formset to the template and displaying it just leaves me with a blank page. Somehow I need to figure out how to get it to show rows for every A (or a queried subset) on the page.
The documentation will be very useful at this point, as this part is more basic Django stuff but usually its just a matter of iterating through every form in the formset like so :
Yeah, I'd gotten similar to that for the template from their examples (and tried copy-pasting that code from you), but still no contents.
I suspect it has something to do with how I'm making the formset, I suspect that I need to be telling it somehow what elements of A type I want it to iterate over to make that set.