At the moment of writing, this is not possible. A ManyToManyField [Django-doc] has a positional to argument with:
class ManyToManyField(to, **options)
A many-to-many relationship. Requires a positional argument: the
class to which the model is related, which works exactly the same as
it does for ForeignKey, including recursive and lazy relationships.
It would also create some confusion: what should the mtm return for some_a.mtm.all()? All related B objects? Tuples of B, C and D objects? What should be the name of the reversed relations?
This however does not mean that you can not emulate such relation. You can make a model that acts like a relation. In fact if you define a ManyToManyField, Django will create a table that stores data from this relation.
So we can define such model like:
class ABCDRel(models.Model):
a = models.ForeignKey(A, on_delete=models.CASCADE, related_name='mtm')
b = models.ForeignKey(B, on_delete=models.CASCADE, related_name='mtm')
c = models.ForeignKey(C, on_delete=models.CASCADE, related_name='mtm')
d = models.ForeignKey(D, on_delete=models.CASCADE, related_name='mtm')
We can then for example obtain a QuerySet of all related ABCDRelations with:
some_a.mtm.all()
Or you can obtain a QuerySet of all related B objects through this relation with:
B.objects.filter(mtm__a=some_a)
The relation can contain extra data, but in essence thus stores "tuples" of how the objects of the models relate to each other.
This thus creates an entity-relation model that looks, more or less, like:
