from django.db import models class ArtistManager(models.Manager): def from_json(self, json): try: return Artist.objects.get(pk=json["id"]) except Artist.DoesNotExist: keys = [f.name for f in Artist._meta.get_fields()] subset = {key:json[key] for key in set(keys) & set(json.keys())} artist = self.create(**subset) return artist class Artist(models.Model): def __str__(self): return self.name id = models.CharField(primary_key=True, max_length=128) name = models.CharField(max_length=255) popularity = models.SmallIntegerField(null=True, blank=True) genres = models.JSONField(null=True) objects = ArtistManager() class AlbumManager(models.Manager): def from_json(self, json): try: return Album.objects.get(pk=json["id"]) except Album.DoesNotExist: artists = [] for artist in json["artists"]: artists.append(Artist.objects.from_json(artist)) del json["artists"] keys = [f.name for f in Album._meta.get_fields()] subset = {key:json[key] for key in set(keys) & set(json.keys())} album = self.create(**subset) for artist in artists: album.artists.add(artist) return album class Album(models.Model): def __str__(self): return self.name id = models.CharField(primary_key=True, max_length=128) name = models.CharField(max_length=255) artists = models.ManyToManyField(Artist) album_type = models.CharField(max_length=255) total_tracks = models.PositiveSmallIntegerField(null=True) image = models.ImageField(upload_to="albums/") objects = AlbumManager() class TrackManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(old=False) def from_json(self, json): artists = [] for artist in json["artists"]: artists.append(Artist.objects.from_json(artist)) del json["artists"] album = Album.objects.from_json(json["album"]) del json["album"] keys = [f.name for f in Track._meta.get_fields()] subset = {key:json[key] for key in set(keys) & set(json.keys())} track = self.create(**subset) track.album = album for artist in artists: track.artists.add(artist) track.save() return track class Track(models.Model): def __str__(self): s = f"'{self.name}'" if self.artists.count() > 0: artists = list(map(lambda a:a.name, self.artists.all())) s += " by " s += " & ".join(artists) if self.explicit: s += " PARENTAL ADVISORY" return s id = models.CharField(primary_key=True, max_length=128) name = models.CharField(max_length=255) artists = models.ManyToManyField(Artist) album = models.ForeignKey(Album, null=True, on_delete=models.SET_NULL) explicit = models.BooleanField(default=False) duration_ms = models.PositiveIntegerField(null=True) popularity = models.PositiveIntegerField(null=True) banter = models.TextField(blank=True) old = models.BooleanField(default=False) objects = TrackManager() #class TrackFeatures(models.Model):