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(
|
child = serializers.PrimaryKeyRelatedField(
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
allow_empty=True,
|
help_text="Required unless a Timer value is provided.",
|
||||||
queryset=models.Child.objects.all(),
|
queryset=models.Child.objects.all(),
|
||||||
required=False,
|
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:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
"start": {"required": False},
|
"start": {
|
||||||
"end": {"required": False},
|
"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):
|
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
|
# of "start" and "end" fields as well as "child" if it is set on the
|
||||||
# Timer entry.
|
# Timer entry.
|
||||||
timer = None
|
timer = None
|
||||||
if "timer" in self.initial_data:
|
if "timer" in attrs:
|
||||||
try:
|
# Remove the "timer" attribute (super validation would fail as it
|
||||||
timer = models.Timer.objects.get(pk=self.initial_data["timer"])
|
# is not a true field on the model).
|
||||||
except models.Timer.DoesNotExist:
|
timer = attrs["timer"]
|
||||||
raise ValidationError({"timer": ["Timer does not exist."]})
|
attrs.pop("timer")
|
||||||
|
|
||||||
if timer.end:
|
if timer.end:
|
||||||
end = timer.end
|
end = timer.end
|
||||||
else:
|
else:
|
||||||
|
@ -142,6 +157,7 @@ class FeedingSerializer(CoreModelWithDurationSerializer, TaggableSerializer):
|
||||||
"child",
|
"child",
|
||||||
"start",
|
"start",
|
||||||
"end",
|
"end",
|
||||||
|
"timer",
|
||||||
"duration",
|
"duration",
|
||||||
"type",
|
"type",
|
||||||
"method",
|
"method",
|
||||||
|
@ -172,7 +188,17 @@ class NoteSerializer(CoreModelSerializer, TaggableSerializer):
|
||||||
class SleepSerializer(CoreModelWithDurationSerializer, TaggableSerializer):
|
class SleepSerializer(CoreModelWithDurationSerializer, TaggableSerializer):
|
||||||
class Meta(CoreModelWithDurationSerializer.Meta):
|
class Meta(CoreModelWithDurationSerializer.Meta):
|
||||||
model = models.Sleep
|
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):
|
class TagSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
|
@ -220,7 +246,16 @@ class TimerSerializer(CoreModelSerializer):
|
||||||
class TummyTimeSerializer(CoreModelWithDurationSerializer, TaggableSerializer):
|
class TummyTimeSerializer(CoreModelWithDurationSerializer, TaggableSerializer):
|
||||||
class Meta(CoreModelWithDurationSerializer.Meta):
|
class Meta(CoreModelWithDurationSerializer.Meta):
|
||||||
model = models.TummyTime
|
model = models.TummyTime
|
||||||
fields = ("id", "child", "start", "end", "duration", "milestone", "tags")
|
fields = (
|
||||||
|
"id",
|
||||||
|
"child",
|
||||||
|
"start",
|
||||||
|
"end",
|
||||||
|
"timer",
|
||||||
|
"duration",
|
||||||
|
"milestone",
|
||||||
|
"tags",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class UserSerializer(serializers.ModelSerializer):
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
|
|
|
@ -6,7 +6,6 @@ from rest_framework.response import Response
|
||||||
from core import models
|
from core import models
|
||||||
|
|
||||||
from . import serializers, filters
|
from . import serializers, filters
|
||||||
from .mixins import TimerFieldSupportMixin
|
|
||||||
|
|
||||||
|
|
||||||
class BMIViewSet(viewsets.ModelViewSet):
|
class BMIViewSet(viewsets.ModelViewSet):
|
||||||
|
@ -37,7 +36,7 @@ class DiaperChangeViewSet(viewsets.ModelViewSet):
|
||||||
filterset_class = filters.DiaperChangeFilter
|
filterset_class = filters.DiaperChangeFilter
|
||||||
|
|
||||||
|
|
||||||
class FeedingViewSet(TimerFieldSupportMixin, viewsets.ModelViewSet):
|
class FeedingViewSet(viewsets.ModelViewSet):
|
||||||
queryset = models.Feeding.objects.all()
|
queryset = models.Feeding.objects.all()
|
||||||
serializer_class = serializers.FeedingSerializer
|
serializer_class = serializers.FeedingSerializer
|
||||||
filterset_class = filters.FeedingFilter
|
filterset_class = filters.FeedingFilter
|
||||||
|
@ -67,7 +66,7 @@ class PumpingViewSet(viewsets.ModelViewSet):
|
||||||
filterset_class = filters.PumpingFilter
|
filterset_class = filters.PumpingFilter
|
||||||
|
|
||||||
|
|
||||||
class SleepViewSet(TimerFieldSupportMixin, viewsets.ModelViewSet):
|
class SleepViewSet(viewsets.ModelViewSet):
|
||||||
queryset = models.Sleep.objects.all()
|
queryset = models.Sleep.objects.all()
|
||||||
serializer_class = serializers.SleepSerializer
|
serializer_class = serializers.SleepSerializer
|
||||||
filterset_class = filters.SleepFilter
|
filterset_class = filters.SleepFilter
|
||||||
|
@ -104,7 +103,7 @@ class TimerViewSet(viewsets.ModelViewSet):
|
||||||
return Response(self.serializer_class(timer).data)
|
return Response(self.serializer_class(timer).data)
|
||||||
|
|
||||||
|
|
||||||
class TummyTimeViewSet(TimerFieldSupportMixin, viewsets.ModelViewSet):
|
class TummyTimeViewSet(viewsets.ModelViewSet):
|
||||||
queryset = models.TummyTime.objects.all()
|
queryset = models.TummyTime.objects.all()
|
||||||
serializer_class = serializers.TummyTimeSerializer
|
serializer_class = serializers.TummyTimeSerializer
|
||||||
filterset_class = filters.TummyTimeFilter
|
filterset_class = filters.TummyTimeFilter
|
||||||
|
|
|
@ -4684,12 +4684,20 @@ components:
|
||||||
child:
|
child:
|
||||||
type: integer
|
type: integer
|
||||||
nullable: true
|
nullable: true
|
||||||
|
description: Required unless a Timer value is provided.
|
||||||
start:
|
start:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
format: date-time
|
||||||
|
description: Required unless a Timer value is provided.
|
||||||
end:
|
end:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
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:
|
duration:
|
||||||
type: string
|
type: string
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -4809,12 +4817,20 @@ components:
|
||||||
child:
|
child:
|
||||||
type: integer
|
type: integer
|
||||||
nullable: true
|
nullable: true
|
||||||
|
description: Required unless a Timer value is provided.
|
||||||
start:
|
start:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
format: date-time
|
||||||
|
description: Required unless a Timer value is provided.
|
||||||
end:
|
end:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
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:
|
duration:
|
||||||
type: string
|
type: string
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -4905,12 +4921,20 @@ components:
|
||||||
child:
|
child:
|
||||||
type: integer
|
type: integer
|
||||||
nullable: true
|
nullable: true
|
||||||
|
description: Required unless a Timer value is provided.
|
||||||
start:
|
start:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
format: date-time
|
||||||
|
description: Required unless a Timer value is provided.
|
||||||
end:
|
end:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
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:
|
duration:
|
||||||
type: string
|
type: string
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
|
Loading…
Reference in New Issue