From a13cf526878a28640ec0f8daf707a3dd64a5040a Mon Sep 17 00:00:00 2001 From: Jens Lauterbach Date: Sat, 20 Nov 2021 18:37:54 +0100 Subject: [PATCH 1/2] Use Slug for Session URL Minor update to the existing code for the session list. The only real change is that the "id" is now the slug of the Talk and the "url" uses the talks slug instead of the pk. Further improvements will be made to the serializer, once the other endpoints/serializers are done. --- devday/talk/api_views.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/devday/talk/api_views.py b/devday/talk/api_views.py index fba48c41..9fc46e42 100644 --- a/devday/talk/api_views.py +++ b/devday/talk/api_views.py @@ -3,15 +3,24 @@ from talk.models import Talk -class SessionSerializer(serializers.ModelSerializer): +class SessionSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.CharField(source="slug") + description = serializers.CharField(source="abstract") + + # TODO Jens: Replace 'event' and 'speakers' with proper nested relationships once their endpoints are done. event = StringRelatedField() - published_speaker = StringRelatedField() + published_speakers = StringRelatedField(many=True) class Meta: model = Talk - fields = ["url", "title", "abstract", "published_speakers", "event"] + fields = ["id", "url", "title", "description", "published_speakers", "event"] + lookup_field = "slug" + extra_kwargs = { + "url": {'lookup_field': 'slug'} + } class SessionViewSet(viewsets.ReadOnlyModelViewSet): queryset = Talk.objects.filter(published_speakers__isnull=False) serializer_class = SessionSerializer + lookup_field = 'slug' From c06911031bebcfdade335407a7658f6d9d6988d8 Mon Sep 17 00:00:00 2001 From: Jens Lauterbach Date: Sun, 21 Nov 2021 17:22:23 +0100 Subject: [PATCH 2/2] Add Initial Speakers Endpoint The endpoint outputs basic information about speakers, including an endpoint for speaker details. At the moment there is no relationship to other entities yet. This will be added at a later point in time, like for example the talks the speaker has given or will give or the events the speaker presented at. --- devday/devday/urls.py | 3 +++ devday/speaker/api_views.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 devday/speaker/api_views.py diff --git a/devday/devday/urls.py b/devday/devday/urls.py index 76d5a31e..eb526fc5 100644 --- a/devday/devday/urls.py +++ b/devday/devday/urls.py @@ -9,6 +9,8 @@ from devday.views import SendEmailView, exception_test_view from rest_framework import routers + +from speaker.api_views import SpeakerViewSet from talk.api_views import SessionViewSet from twitterfeed.views import TwitterwallView @@ -16,6 +18,7 @@ router = routers.DefaultRouter() router.register(r"sessions", SessionViewSet) +router.register(r"speakers", SpeakerViewSet) urlpatterns = [ url(r"^api/", include(router.urls)), diff --git a/devday/speaker/api_views.py b/devday/speaker/api_views.py new file mode 100644 index 00000000..d77fb4fc --- /dev/null +++ b/devday/speaker/api_views.py @@ -0,0 +1,31 @@ +from rest_framework import serializers, viewsets + +from speaker.models import Speaker + + +class SpeakerSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.CharField(source="slug") + image = serializers.ImageField(source="public_image", use_url=True, allow_null=False, allow_empty_file=False) + + class Meta: + model = Speaker + fields = ["id", "url", "name", "short_biography", "position", "image"] + lookup_field = "slug" + extra_kwargs = { + "url": {'lookup_field': 'slug'} + } + + def to_representation(self, instance): + representation = super().to_representation(instance) + + # TODO Jens: This probably can be solved more elegantly with a mixin. + if not representation["image"]: + representation["image"] = "" + + return representation + + +class SpeakerViewSet(viewsets.ReadOnlyModelViewSet): + queryset = Speaker.objects.all() + serializer_class = SpeakerSerializer + lookup_field = "slug"