Consider the following models.py
, where a Group contains multiple Persons who each have zero or more Phone numbers. In this particular case, Persons who share a Group will often share at least one Phone number, so a many-to-many relationship is used.
class Group(models.Model):
name = models.CharField(max_length=30)
class Person(models.Model):
group = models.ForeignKey(Group)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
class Phone(models.Model):
persons = models.ManyToManyField(Person)
number = models.CharField(max_length=30)
I would like to show these models in the Django admin, in a single view, as shown below.
class PersonInline(admin.StackedInline):
model = Person
class PhoneInline(admin.StackedInline):
model = Phone # also tried: Phone.persons.through
@admin.register(Group)
class GroupAdmin(admin.ModelAdmin):
inlines = [PersonInline, PhoneInline]
However, there is no foreign key between Group and Phone, so this raises a SystemCheckError
(one of the following):
<class 'myapp.admin.PhoneInline'>: (admin.E202) 'myapp.Phone' has no ForeignKey to 'myapp.Group'.
<class 'myapp.admin.PhoneInline'>: (admin.E202) 'myapp.Phone_persons' has no ForeignKey to 'myapp.Group'.
Is it possible to make this work through the Person model? The goal is for the Phone inline to show phone number records for all Persons in the Group (bonus: when adding a new Phone, the Person SelectMultiple widget will need to only show other Persons in the Group). I would prefer to avoid modifying any templates. A third-party app could be integrated if necessary. I can use Django 1.10 or 1.11.
Thanks!
I solved this by slightly modifying my requirements. Rather than requiring a relationship between
Phone
andPerson
only, I added another many-to-one relationship: betweenPhone
andGroup
. For my particular case, it actually works out better this way; and aGroup
should cascade to both relatedPerson
s and relatedPhone
s on delete.There is no change to the
admin.py
shown in the question. Themodels.py
has one more line in thePhone
class, a ForeignKey field:The "bonus" above requires that the ManyToManyField form widget in the
Person
inline show only thosePerson
s that are in the sameGroup
. For this, two functions can be added toadmin.py
: