0

I'm very new to both Django and the Django Rest Framework, and I'm struggling with building up a particular JSON response. I have two models, like so:

class Artist(models.model):
  artist_id = models.CharField(
    max_length=256,
    primary_key=True,
  )
  name = models.CharField(
    max_length=256,
    null=False,
    blank=False,
  )
  birthplace =  models.CharField(
    max_length=256,
    null=False,
    blank=False,
  )

class Album(models.Model):
  artist = models.ForeignKey(
    Artist,
    on_delete=models.DO_NOTHING,
    db_constraint=False,
    null=True,
  )
  name = models.CharField(
    max_length=256,
    null=False,
    blank=False,
  )
  label = models.CharField(
    max_length=256,
    null=False,
    blank=False,
  )

I'm trying to build a JSON response that looks like this, where the albums are nested inside the artist:

{
    "artist_id": "A123",
    "name": "Bob Dylan",
    "birtplace": "Duluth, Minnesota",
    "albums": [
        {
            "id": 123,
            "name": "Bob Dylan",
            "label": "Columbia"
        },
        {
            "id": 123,
            "name": "The Freewheelin' Bob Dylan",
            "label": "Columbia"
        }
    ]
}

Is this even possible? I was looking into select_related, but that doesn't seem to work as I feel like I need to 'hit' the Artist table first, and there is no relationship defined in the direction of Artist to Album.

Any help would be greatly appreciated.

1 Answer 1

1

If you need to make a serializer that matches the JSON response that provides in your question, this will be something like that:

class AlbumSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField(read_only=True)
    label = serializers.CharField(read_only=True)

class ArtistSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    artist_id = serializers.CharField(read_only=True) # I suggest to use the defult id field that comes with Django for now.
    name = serializers.CharField(read_only=True)
    birthplace = serializers.CharField(read_only=True)

This is a simple serializer, right? Let's build your views and assume this is a GET request and I prefer using APIView

class ListApi(APIView):

    def get(self, request):

        artist = Artist.objects.all()

        artist_serializer = ArtistSerializer(albums, many=True).data
    
        '''
        artist_serializer will give us this data, right?

        {
            "artist_id": "A123",
            "name": "Bob Dylan",
            "birtplace": "Duluth, Minnesota",
        }

        So, for every artist in this data have multiple Album, so we need to fetch all albums that belong to this artist.
        '''

        for artist in artist_serializer:
            albums = Album.objects.filter(artist=artist['id'])
            artist['albums'] = AlbumSerializer(albums, many=True).data

        return Response(artist_serializer)

If you face any issues with understanding the code, feel free to ask!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.