Post save action to update another model

I have models Song and Playlist. Playlist is a list of several (or all) songs in specific order. Song can be listed only once.

Every time a new Song is created it should be added to Playlist as last item.
Where should I put that code ?
Should I create a class PlaylistManager(models.Manager) ?
Or how to approach this ?

class Song(models.Model):
    author = models.CharField(max_length=50)
    title = models.CharField(max_length=50)
    lyrics = models.TextField()

class Playlist(models.Model):
    song = models.OneToOneField(Playlist,on_delete=models.CASCADE,primary_key=True,)
    order = models.IntegerField()        

Do I understand correctly that

  1. A playlist can have multiple songs
  2. A song can be in multiple playlists (e. g. “I’m only happy when it rains” could be in both a “Garbage top songs” playlist and a “90’s” playlist)

?

I think then what you want is this:

class Song(models.Model):
    author = models.CharField(max_length=50)
    title = models.CharField(max_length=50)
    lyrics = models.TextField()
    playlists = models.ManyToManyField(Playlist, on_delete=models.CASCADE)


class Playlist(models.Model):
    title = models.CharField(max_length=50)

Someone please correct me if I’m wrong, but I think that the way Django works, the most recently added Song will be at the end of the returned QuerySet that you get by using e. g. Playlist.song_set.all().

You can read about ManyToMany relationships in the Django docs.

Hope this helps :slight_smile:

Thanks for your reply.

NO. In this case it is specific request that there is only 1 playlist and that song can be only once on this playlist. Also, the song does not have to be on the playlist. So the code I wrote is correct in this specific “strange” case. So could I kindly ask you to say what you would do in that specific case I wrote ?

In that case I think you want a Many-to-One relationship, which you achieve by using a Foreignkey. Also you need to allow for blank inputs/null values in your database, since you want to allow for Song instances that aren’t linked to any playlist.

class Song(models.Model):
    author = models.CharField(max_length=50)
    title = models.CharField(max_length=50)
    lyrics = models.TextField()
    playlist = models.ForeignKey(Playlist, on_delete=models.CASCADE, blank=True, null=True)


class Playlist(models.Model):
    title = models.CharField(max_length=50)

(Actually I shouldn’t have included the on_delete argument in my earlier example, since it’s not needed for ManyToMany fields)

If there is only 1 playlist, why have a model describing it? If I had this situation, I would only have a Song model, with a “sequence” field identifying its position in the list. I would allow Nulls in that field, and so any Song not in the playlist would have a sequence of None.

1 Like

@KenWhitesell …and that’s exactly what I had in my previous project but using PHP Laravel :slight_smile:
Thanks for reminding me… So I think I’ll go this way…

@datalowe thank you for answering!!! For now I’ll go with the easiest (kiss) solution proposed by KenWhitesell