Skip to content

Commit

Permalink
Add Song resources to API and update documentation
Browse files Browse the repository at this point in the history
This commit adds a new resource, Song, to the current music API. Changes include registering the new SongViewSet to the router in urls.py, adding SongSerializer in serializers.py and updating the views in views.py. The getString method for Song model in models.py has also been updated. Additionally, the documentation (index.md) has been updated to reflect these changes.
  • Loading branch information
lipemorais committed May 15, 2024
1 parent 01b806f commit 01405d3
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 6 deletions.
49 changes: 48 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ class AlbumSerializer(serializers.Serializer):
2. With the fields `title`, `artist`, `release_year` with it respective fields
3. We also need to list the fields inside the class Meta

Additionally we need to add 2 methods to let DRF know how to save and how to update the Albums.
Additionally, we need to add 2 methods to let DRF know how to save and how to update the Albums.

The first is `create`

Expand Down Expand Up @@ -518,6 +518,53 @@ Now we have 2 resources here, artists and albums

I hope that at this time you understand the amount of shortcuts DRF gives you at the same time, if you want to customize it, it's still possible.

## Building an API - Part III
### Easy version
We are going to start from the urls one more time. We will add the route for the songs in our `music.urls` like in the snippet below
```python
from django.urls import path, include
from rest_framework import routers

from .views import ArtistViewSet, AlbumViewSet, SongViewSet

router = routers.DefaultRouter()
router.register(r'artists', ArtistViewSet)
router.register(r'albums', AlbumViewSet)
# Add this new line below
router.register(r'songs', SongViewSet)

urlpatterns = [
path('', include(router.urls)),
# path('', views.index, name='index'),
]
```
After this we are going to create the `SongViewSet` in our `music.views` file using a `ModelViewSet` like in the snippet below. Also update Don't forget to add the import for the `SongSerializer` in your imports

```python
from music.serializers import ArtistSerializer, AlbumSerializer, SongSerializer

class SongViewSet(viewsets.ModelViewSet):
queryset = Song.objects.all()
serializer_class = SongSerializer
```

At this point the `SongSerializer` doesn't exist yet, so now we are going to create it. Here also update the imports for the models including the `Song` model. Here there is a snippet so you see the changes you have to do on you `music.serializers` file.

```python
from music.models import Artist, Album, Song

class SongSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Song
fields = ['author', 'title', 'artist', 'album', 'duration']
```

With this part done you will be able to run you application and see something like this on you api with all 3 resource working in your API, Artist, Album and Song. 🥳

![final-version.png](images/final-version.png)

Now you api is complete! Congratulations! 🍾🎉🎊

## Bonus content

### Serializers deep dive
Expand Down
3 changes: 3 additions & 0 deletions first_api/music/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ class Song(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE) # Artist or band name
album = models.ForeignKey(Album, on_delete=models.CASCADE) # Album the song belongs to
duration = models.IntegerField() # Duration of the song in seconds

def __str__(self):
return f'{self.title} - {self.artist} - {self.album}'
8 changes: 7 additions & 1 deletion first_api/music/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework import serializers

from music.models import Artist, Album
from music.models import Artist, Album, Song


class ArtistSerializer(serializers.HyperlinkedModelSerializer):
Expand Down Expand Up @@ -35,3 +35,9 @@ def update(self, album, validated_data):
album.save()

return album


class SongSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Song
fields = ['author', 'title', 'artist', 'album', 'duration']
4 changes: 2 additions & 2 deletions first_api/music/urls.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from django.urls import path, include
from rest_framework import routers

from . import views
from .views import ArtistViewSet, AlbumViewSet
from .views import ArtistViewSet, AlbumViewSet, SongViewSet

router = routers.DefaultRouter()
router.register(r'artists', ArtistViewSet)
router.register(r'albums', AlbumViewSet)
router.register(r'songs', SongViewSet)

urlpatterns = [
path('', include(router.urls)),
Expand Down
9 changes: 7 additions & 2 deletions first_api/music/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response

from music.models import Artist, Album
from music.serializers import ArtistSerializer, AlbumSerializer
from music.models import Artist, Album, Song
from music.serializers import ArtistSerializer, AlbumSerializer, SongSerializer


def index(_request):
Expand Down Expand Up @@ -53,3 +53,8 @@ def destroy(self, request, pk=None):
album = get_object_or_404(Album, pk=pk)
album.delete()
return Response(status=status.HTTP_204_NO_CONTENT)


class SongViewSet(viewsets.ModelViewSet):
queryset = Song.objects.all()
serializer_class = SongSerializer

0 comments on commit 01405d3

Please sign in to comment.