Skip to content

Commit

Permalink
Added nested writable relationship
Browse files Browse the repository at this point in the history
Custom serializer ref
  • Loading branch information
octaflop committed Sep 3, 2017
1 parent 708c7b4 commit 34a43b6
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 2 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,16 @@ Now we're going to play with Django's ORM and admin: One of the main selling-poi
6. And we also add an `admin.py` file for easy management of the DB.
7. We can visit `localhost:8000/admin` and `localhost:8000/db/songs`; etc for more views.
8. Because our urls are named, we can use the `{% url %}` django template tag to directly link to a model's page (or the list page).

## 4. `web_endpoint`

Instead of creating new models, we'll use the old ones from `web_db` to create *Endpoints*.

Endpoints are simply api endpoints which can be used by javascript or mobile to make changes to the DB.

1. Spin up `web_endpoints` via `./manage.py startapp web_endpoints` and `mv` it to `apps`
2. Add `web_endpoints` to our `INSTALLED_APPS` list
3. Ensure that `[rest_framework](http://www.django-rest-framework.org)` has been added to `INSTALLED_APPS`
3. Create serializers for our Album and Song models in `web_endpoints/serializers.py`.
4. We then use ViewSets and Routers to link everything else up.
5. We will also write a custom creation method for the nested serializer.
9 changes: 7 additions & 2 deletions apps/django_music/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,18 @@
'django.contrib.staticfiles',
]

THIRD_PARTY_APPS = [
'rest_framework'
]

OUR_APPS = [
'web_pages',
'web_app',
'web_db'
'web_db',
'web_endpoints'
]

INSTALLED_APPS = DJANGO_APPS + OUR_APPS
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + OUR_APPS

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
Expand Down
6 changes: 6 additions & 0 deletions apps/django_music/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
from web_pages.views import basic_web_page
from web_app.views import basic_web_app, dynamic_web_app

apipatterns = [
url(r'^v1/', include('web_endpoints.urls', namespace='v1')),
]

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^pages/$', basic_web_page), # the web_pages app. We call the view's callable function
Expand All @@ -27,4 +31,6 @@
url(r'^app/song/$', dynamic_web_app),
# the web_db app. In this case, we'll include instead of specifying each view
url(r'^db/', include('web_db.urls', namespace='db')),
# And finally, our endpoints
url(r'^api/', include(apipatterns, namespace='api')),
]
Empty file added apps/web_endpoints/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions apps/web_endpoints/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
5 changes: 5 additions & 0 deletions apps/web_endpoints/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class WebEndpointsConfig(AppConfig):
name = 'web_endpoints'
Empty file.
3 changes: 3 additions & 0 deletions apps/web_endpoints/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.db import models

# Create your models here.
33 changes: 33 additions & 0 deletions apps/web_endpoints/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from rest_framework import serializers

from web_db.models import Album, Song


class BasicSongSerializer(serializers.ModelSerializer):

class Meta:
model = Song
fields = ('title', 'track', 'duration',)


class AlbumSerializer(serializers.ModelSerializer):
songs = BasicSongSerializer(many=True, source='song_set')

class Meta:
model = Album
fields = ('title', 'artist', 'year', 'songs')

def create(self, data):
songs = data.pop('song_set')
album = Album.objects.create(**data)
for song in songs:
Song.objects.create(album=album, **song)
return album


class SongSerializer(serializers.ModelSerializer):
album = AlbumSerializer()

class Meta:
model = Song
fields = ('title', 'track', 'duration', 'album',)
3 changes: 3 additions & 0 deletions apps/web_endpoints/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
11 changes: 11 additions & 0 deletions apps/web_endpoints/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.conf.urls import url, include
from web_endpoints.views import AlbumViewSet, SongViewSet
from rest_framework.routers import DefaultRouter

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

urlpatterns = [
url(r'', include(router.urls)),
]
15 changes: 15 additions & 0 deletions apps/web_endpoints/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from rest_framework import viewsets

from web_db.models import Album, Song

from web_endpoints.serializers import AlbumSerializer, SongSerializer


class AlbumViewSet(viewsets.ModelViewSet):
queryset = Album.objects.all()
serializer_class = AlbumSerializer


class SongViewSet(viewsets.ModelViewSet):
queryset = Song.objects.all()
serializer_class = SongSerializer
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Django==1.11.4
ipython==6.1.0
djangorestframework==3.6.4
ipdb==0.10.3

0 comments on commit 34a43b6

Please sign in to comment.