I'm new at Django and have a few problems getting my mind around manytomany relatiosnhips and Manytoone (i.e Foreign key).
My setup is this.
I have class A, Class B, Class C
Every Class B object must belong to a Class A object. They cannot belong to more than one Class A object. A more practical example could be if Class A is a Music Band and class B is a song with that Band. Most Bands will have more than one song but every song must belong to a Band (in this example a song can never have multiple Bands).
Class C is a listing of individual Band members. So every band member can be associated with an arbitrary number of songs as well as an arbitrary number of Bands. In other words a member of Band X can also be a member of Band Y.
My question then would be
How would i use the ForeignKey and ManytoMany relationships in this context?
This example is contrived just to make my situation easier to understand and to help me explain my issue. I would like the admin to display for each Class C object what Class B objects or Class A objects that Class C belongs go. The same goes for Class B and Class A.
If you look at Class A objects you should be able to se a listing of all Class B objects that belong to that particular Class A object.
Any and all input appreciated.
Here's how I'd set it up (in your models.py
)
class Member(models.Model):
name = models.CharField(max_length=100)
...
def __unicode__(self):
return self.name
class Band(models.Model):
name = models.CharField(max_length=100)
members = models.ManyToManyField(Member)
...
def __unicode__(self):
return self.name
class Song(models.Model):
name = models.CharField(max_length=100)
band = models.ForeignKey(Band)
...
def __unicode__(self):
return self.name
Set up like this:
member.band_set.all()
gives you all bands a member belongs toband.members.all()
gives you the members of a bandsong.band
gives you the band for that songband.song_set.all()
gives you all songs for a bandNote that the band_set
on member and the song_set
on band are "reverse" relationships. They aren't explicitly defined in the models, but Django sets them up for you transparently. You can customize these by using the related_name
parameter on the field definition. Example:
class Band(models.Model):
members = models.ManyToManyField(Member,related_name='bands')
would let you get all the bands for a member as follows:
member.bands.all()
The admin will automatically provide the following:
However, if you want to see songs for a band, you'll have to do a little admin customization.
In your admin.py
:
from django.contrib import admin
class SongInline(admin.StackedInline):
model = Song
extra = 1
class BandAdmin(admin.ModelAdmin):
inlines = [SongInline]
admin.site.register(Band,BandAdmin)
admin.site.register(Member)
admin.site.register(Song)
This will let you view the songs right from the admin page -- and edit or add them as well! By following this template you could show all bands for a member as well.
You can get a more detailed introduction to the admin customization at http://docs.djangoproject.com/en/dev/intro/tutorial02/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With