I have begun a task to map webs of “techniques.” The idea here is to map decomposition and reuse of techniques, and to do it with an explicit table for the link relation so as to add detail specific to that link.
name = models.CharField(max_length=50, default="")
combines = models.ManyToManyField('Technique', through='CombineLink', through_fields=["combines","necessary_for"], related_name='necessary_for', blank=True)
necessary_for = models.ForeignKey(Technique, related_name='is_reused_in', on_delete=models.CASCADE, null=True)
combines = models.ForeignKey(Technique, related_name='uses', on_delete=models.CASCADE, null=True)
My initial problem was that I didn’t have ‘through_fields’ set, but although I didn’t get an error, I was striking a problem where the reverse_accessor was returning a queryset of CombineLinks, not a queryset of Techniques. Adding the through_fields list seems to have resolved this.
But, the reverse accessor on CombineLink fields can be invoked from a technique, but returns a queryset of CombineLink objects. This is not exactly what I expected, but is useful.
waterwheel = Technique.objects.create(name="waterwheel")
flourmilling = Technique.objects.create(name="flourmilling")
waterwheel.necessary_for.all() # field name
<QuerySet [<Technique: flourmilling (c7a74122-12b8-47c5-beb2-740c4e571429)>]>
waterwheel.is_reused_in.all() # reverse_accessor
<QuerySet [<CombineLink: (810ecd64)-(waterwheel,flourmilling)>]>
I guess my question is ‘should I update my expectation? Or have I misconfigured this, e.g. by ommitting ‘symmetrical=False’ or something else?’