Reputation: 8144
My models:
class Person(SchoolModel):
first_name = models.CharField(max_length=75)
last_surname = models.CharField(max_length=75)
students = models.ManyToManyField('self', through='StudentParent',
through_fields=('parent', 'student'), related_name='+')
parents = models.ManyToManyField('self', through='StudentParent',
through_fields=('student', 'parent'), related_name='+')
class StudentParent(SchoolModel):
student = models.ForeignKey('Person')
parent = models.ForeignKey('Person')
relation = models.CharField(max_length=26)
class Meta:
unique_together = ('student', 'parent')
As seen above Person model has two m2m relationships to itself: students, and parents. Each person may have many students on the same Person table, and also many parents.
However, Django does not allow this:
Person: (models.E003) The model has two many-to-many relations through
the intermediate model 'StudentParent'.
I don't see why Django refuses to do so especially since it does not save or validate m2m fields with custom intermediary tables. On the other hand, I only need to use these fields to retrieve related models more easily. Examples:
person_obj.students.all()
Person.objects.filter(parents__in=another_person_queryset)
So my question is, 1) Is there a way around this issue in Django1.11 (making such 2 m2m fields possible via configuration etc)? 2) is there a way to make this happen for a read only scenario by other means?
Would using a proxy to the intermediary model trick django to make 1) happen? Would using custom managers help make 2) happen? What would be the shortest, neatest path?
Note: I am aware a similar question is asked before, however that is a little different and a little old.
Upvotes: 3
Views: 1686
Reputation: 8144
Seems tricking Django via a proxy model works for the purposes I described above (retrieving related data of model instances or within filtering querysets). So the models become:
class Person(SchoolModel):
first_name = models.CharField(max_length=75)
last_surname = models.CharField(max_length=75)
students = models.ManyToManyField('self', through='StudentParentProxy', # << !!!!!!
through_fields=('parent', 'student'), related_name='+')
parents = models.ManyToManyField('self', through='StudentParent',
through_fields=('student', 'parent'), related_name='+')
class StudentParent(SchoolModel):
student = models.ForeignKey('Person')
parent = models.ForeignKey('Person')
relation = models.CharField(max_length=26)
class Meta:
unique_together = ('student', 'parent')
class StudentParentProxy(StudentParent):
class Meta:
proxy = True # << !!!!!!
Upvotes: 2