Say I'm working on a database that tracks the members in different bands. Each Band will have multiple Musicians, but each Musician can only be in one Band. If my models look like this:
class Band(models.Model):
id = models.IntegerField().primary_key = True
name = models.CharField(max_length=2083, blank=True, null=True)
members = models.ManyToManyField('Musician', blank=True)
class Musician(models.Model):
id = models.IntegerField().primary_key = True
name = models.CharField(max_length=2083, blank=True, null=True)
<NAME OF BAND>
After adding the Musicians in my db to the Bands, when I go to edit a Musician on the Admin page I want to see which Band they are in. What do I need to add to my models or my ModelAdmins to make that happen?
Right now where the above say I have:
member_of: Band.name
I would expect that to return the name of the band but it's giving me the name of the Musician
Quick Edit: I forgot to mention that I have readonly_fields = ["member_of"]
in my MusicianAdmin
If you specify a ManyToManyField
(or any other relation), you can query in reverse automatically with:
my_musician.band_set.all()
This is a QuerySet
of all Band
s related to the Musician
named musician
.
You can add these to your ModelAdmin
for the musicians with:
class BandMembersInline(admin.TabularInline):
model = Band.members.through
@admin.register(Musician)
class MusicianAdmin(admin.ModelAdmin):
inlines = [
BandMembersInline,
]
but each
Musician
can only be in oneBand
.
If each musician can only have one band, the modeling is wrong. In that case you model this with a ForeignKey
[Django-doc] from Musician
to Band
:
class Band(models.Model):
name = models.CharField(max_length=2083)
def __str__(self):
return self.name
class Musician(models.Model):
name = models.CharField(max_length=2083)
band = models.ForeignKey(
Band, related_name='members', on_delete=models.CASCADE
)
as admin, you can then use:
class MusicianInline(admin.TabularInline):
model = Musician
@admin.register(Musician)
class MusicianAdmin(admin.ModelAdmin):
# …
pass
@admin.register(Band)
class BandAdmin(admin.ModelAdmin):
# …
inlines = [MusicianInline]