mirror of https://github.com/snachodog/mybuddy.git
Add `timer` field data to OpenAPI schema (#474)
* Add timer as an actual field on the duration serializer This change enables the timer field to be part of the generated OpenAPI schema.
This commit is contained in:
parent
5ab2fce0d0
commit
1a19f05130
|
@ -1,29 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from collections import OrderedDict
|
||||
|
||||
from rest_framework.response import Response
|
||||
|
||||
|
||||
class TimerFieldSupportMixin:
|
||||
def options(self, request, *args, **kwargs):
|
||||
"""
|
||||
Add information about the optional "timer" field.
|
||||
"""
|
||||
meta = self.metadata_class()
|
||||
data = meta.determine_metadata(request, self)
|
||||
post = data.get("actions").get("POST") # type: OrderedDict
|
||||
post["timer"] = OrderedDict(
|
||||
{
|
||||
"type": "integer",
|
||||
"required": False,
|
||||
"read_only": False,
|
||||
"label": "Timer",
|
||||
"details": "ID for an existing Timer, may be used in place of the "
|
||||
"`start`, `end`, and/or `child` fields. ",
|
||||
}
|
||||
)
|
||||
details = "Required unless a value is provided in the `timer` field."
|
||||
post["child"]["details"] = details
|
||||
post["start"]["details"] = details
|
||||
post["end"]["details"] = details
|
||||
return Response(data)
|
|
@ -39,16 +39,30 @@ class CoreModelWithDurationSerializer(CoreModelSerializer):
|
|||
|
||||
child = serializers.PrimaryKeyRelatedField(
|
||||
allow_null=True,
|
||||
allow_empty=True,
|
||||
help_text="Required unless a Timer value is provided.",
|
||||
queryset=models.Child.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
|
||||
timer = serializers.PrimaryKeyRelatedField(
|
||||
allow_null=True,
|
||||
help_text="May be used in place of the Start, End, and/or Child values.",
|
||||
queryset=models.Timer.objects.all(),
|
||||
required=False,
|
||||
write_only=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
extra_kwargs = {
|
||||
"start": {"required": False},
|
||||
"end": {"required": False},
|
||||
"start": {
|
||||
"help_text": "Required unless a Timer value is provided.",
|
||||
"required": False,
|
||||
},
|
||||
"end": {
|
||||
"help_text": "Required unless a Timer value is provided.",
|
||||
"required": False,
|
||||
},
|
||||
}
|
||||
|
||||
def validate(self, attrs):
|
||||
|
@ -56,11 +70,12 @@ class CoreModelWithDurationSerializer(CoreModelSerializer):
|
|||
# of "start" and "end" fields as well as "child" if it is set on the
|
||||
# Timer entry.
|
||||
timer = None
|
||||
if "timer" in self.initial_data:
|
||||
try:
|
||||
timer = models.Timer.objects.get(pk=self.initial_data["timer"])
|
||||
except models.Timer.DoesNotExist:
|
||||
raise ValidationError({"timer": ["Timer does not exist."]})
|
||||
if "timer" in attrs:
|
||||
# Remove the "timer" attribute (super validation would fail as it
|
||||
# is not a true field on the model).
|
||||
timer = attrs["timer"]
|
||||
attrs.pop("timer")
|
||||
|
||||
if timer.end:
|
||||
end = timer.end
|
||||
else:
|
||||
|
@ -142,6 +157,7 @@ class FeedingSerializer(CoreModelWithDurationSerializer, TaggableSerializer):
|
|||
"child",
|
||||
"start",
|
||||
"end",
|
||||
"timer",
|
||||
"duration",
|
||||
"type",
|
||||
"method",
|
||||
|
@ -172,7 +188,17 @@ class NoteSerializer(CoreModelSerializer, TaggableSerializer):
|
|||
class SleepSerializer(CoreModelWithDurationSerializer, TaggableSerializer):
|
||||
class Meta(CoreModelWithDurationSerializer.Meta):
|
||||
model = models.Sleep
|
||||
fields = ("id", "child", "start", "end", "duration", "nap", "notes", "tags")
|
||||
fields = (
|
||||
"id",
|
||||
"child",
|
||||
"start",
|
||||
"end",
|
||||
"timer",
|
||||
"duration",
|
||||
"nap",
|
||||
"notes",
|
||||
"tags",
|
||||
)
|
||||
|
||||
|
||||
class TagSerializer(serializers.HyperlinkedModelSerializer):
|
||||
|
@ -220,7 +246,16 @@ class TimerSerializer(CoreModelSerializer):
|
|||
class TummyTimeSerializer(CoreModelWithDurationSerializer, TaggableSerializer):
|
||||
class Meta(CoreModelWithDurationSerializer.Meta):
|
||||
model = models.TummyTime
|
||||
fields = ("id", "child", "start", "end", "duration", "milestone", "tags")
|
||||
fields = (
|
||||
"id",
|
||||
"child",
|
||||
"start",
|
||||
"end",
|
||||
"timer",
|
||||
"duration",
|
||||
"milestone",
|
||||
"tags",
|
||||
)
|
||||
|
||||
|
||||
class UserSerializer(serializers.ModelSerializer):
|
||||
|
|
|
@ -6,7 +6,6 @@ from rest_framework.response import Response
|
|||
from core import models
|
||||
|
||||
from . import serializers, filters
|
||||
from .mixins import TimerFieldSupportMixin
|
||||
|
||||
|
||||
class BMIViewSet(viewsets.ModelViewSet):
|
||||
|
@ -37,7 +36,7 @@ class DiaperChangeViewSet(viewsets.ModelViewSet):
|
|||
filterset_class = filters.DiaperChangeFilter
|
||||
|
||||
|
||||
class FeedingViewSet(TimerFieldSupportMixin, viewsets.ModelViewSet):
|
||||
class FeedingViewSet(viewsets.ModelViewSet):
|
||||
queryset = models.Feeding.objects.all()
|
||||
serializer_class = serializers.FeedingSerializer
|
||||
filterset_class = filters.FeedingFilter
|
||||
|
@ -67,7 +66,7 @@ class PumpingViewSet(viewsets.ModelViewSet):
|
|||
filterset_class = filters.PumpingFilter
|
||||
|
||||
|
||||
class SleepViewSet(TimerFieldSupportMixin, viewsets.ModelViewSet):
|
||||
class SleepViewSet(viewsets.ModelViewSet):
|
||||
queryset = models.Sleep.objects.all()
|
||||
serializer_class = serializers.SleepSerializer
|
||||
filterset_class = filters.SleepFilter
|
||||
|
@ -104,7 +103,7 @@ class TimerViewSet(viewsets.ModelViewSet):
|
|||
return Response(self.serializer_class(timer).data)
|
||||
|
||||
|
||||
class TummyTimeViewSet(TimerFieldSupportMixin, viewsets.ModelViewSet):
|
||||
class TummyTimeViewSet(viewsets.ModelViewSet):
|
||||
queryset = models.TummyTime.objects.all()
|
||||
serializer_class = serializers.TummyTimeSerializer
|
||||
filterset_class = filters.TummyTimeFilter
|
||||
|
|
|
@ -4684,12 +4684,20 @@ components:
|
|||
child:
|
||||
type: integer
|
||||
nullable: true
|
||||
description: Required unless a Timer value is provided.
|
||||
start:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Required unless a Timer value is provided.
|
||||
end:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Required unless a Timer value is provided.
|
||||
timer:
|
||||
type: integer
|
||||
writeOnly: true
|
||||
nullable: true
|
||||
description: May be used in place of the Start, End, and/or Child values.
|
||||
duration:
|
||||
type: string
|
||||
readOnly: true
|
||||
|
@ -4809,12 +4817,20 @@ components:
|
|||
child:
|
||||
type: integer
|
||||
nullable: true
|
||||
description: Required unless a Timer value is provided.
|
||||
start:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Required unless a Timer value is provided.
|
||||
end:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Required unless a Timer value is provided.
|
||||
timer:
|
||||
type: integer
|
||||
writeOnly: true
|
||||
nullable: true
|
||||
description: May be used in place of the Start, End, and/or Child values.
|
||||
duration:
|
||||
type: string
|
||||
readOnly: true
|
||||
|
@ -4905,12 +4921,20 @@ components:
|
|||
child:
|
||||
type: integer
|
||||
nullable: true
|
||||
description: Required unless a Timer value is provided.
|
||||
start:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Required unless a Timer value is provided.
|
||||
end:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Required unless a Timer value is provided.
|
||||
timer:
|
||||
type: integer
|
||||
writeOnly: true
|
||||
nullable: true
|
||||
description: May be used in place of the Start, End, and/or Child values.
|
||||
duration:
|
||||
type: string
|
||||
readOnly: true
|
||||
|
|
Loading…
Reference in New Issue