Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 548489a539 | |||
| 887b53300a | |||
| f692fe7c98 | |||
| 017ae3d240 | |||
| b57413023b | |||
| 4014c69689 | |||
| 7bb4700003 | |||
| 86c1675c58 | |||
| 81f0b1a2ea | |||
| 298a9745df |
@@ -2,6 +2,19 @@
|
||||
Changelog
|
||||
#########
|
||||
|
||||
|
||||
**********
|
||||
**1.15.0**
|
||||
**********
|
||||
|
||||
*Release date: Apr 01, 2019*
|
||||
|
||||
- **ADDED:** added ``is_list_view`` and ``has_list_response`` extension points to ``SwaggerAutoSchema`` (:issue:`331`)
|
||||
- **IMPROVED:** updated ``swagger-ui`` to version 3.22.0
|
||||
- **IMPROVED:** updated ``ReDoc`` to version 2.0.0-rc.4
|
||||
- **FIXED:** ``ListModelMixin`` will now always be treated as a list view (:issue:`306`)
|
||||
- **FIXED:** non-primtive values in field ``choices`` will now be handled properly (:issue:`340`)
|
||||
|
||||
**********
|
||||
**1.14.0**
|
||||
**********
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ This library generates OpenAPI 2.0 documents. The authoritative specification fo
|
||||
be the official documentation over at `swagger.io <https://swagger.io/>`__ and the `OpenAPI 2.0 specification
|
||||
page <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md>`__.
|
||||
|
||||
Beause the above specifications are a bit heavy and convoluted, here is a general overview of how the specification
|
||||
Because the above specifications are a bit heavy and convoluted, here is a general overview of how the specification
|
||||
is structured, starting from the root ``Swagger`` object.
|
||||
|
||||
* :class:`.Swagger` object
|
||||
|
||||
Generated
+795
-83
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "drf-yasg",
|
||||
"dependencies": {
|
||||
"redoc": "^2.0.0-rc.2",
|
||||
"swagger-ui-dist": "^3.21.0"
|
||||
"redoc": "^2.0.0-rc.4",
|
||||
"swagger-ui-dist": "^3.22.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -272,7 +272,8 @@ class FieldInspector(BaseInspector):
|
||||
assert not isinstance(field, openapi.SwaggerDict), "passed field is already a SwaggerDict object"
|
||||
title = force_real_str(field.label) if field.label else None
|
||||
title = title if swagger_object_type == openapi.Schema else None # only Schema has title
|
||||
description = force_real_str(field.help_text) if field.help_text else None
|
||||
help_text = getattr(field, 'help_text', None)
|
||||
description = force_real_str(help_text) if help_text else None
|
||||
description = description if swagger_object_type != openapi.Items else None # Items has no description either
|
||||
|
||||
def SwaggerType(existing_object=None, **instance_kwargs):
|
||||
@@ -341,6 +342,9 @@ class ViewInspector(BaseInspector):
|
||||
#: methods that are assumed to require a request body determined by the view's ``serializer_class``
|
||||
implicit_body_methods = ('PUT', 'PATCH', 'POST')
|
||||
|
||||
#: methods which are assumed to return a list of objects when present on non-detail endpoints
|
||||
implicit_list_response_methods = ('GET',)
|
||||
|
||||
# real values set in __init__ to prevent import errors
|
||||
field_inspectors = [] #:
|
||||
filter_inspectors = [] #:
|
||||
@@ -374,20 +378,30 @@ class ViewInspector(BaseInspector):
|
||||
"""
|
||||
raise NotImplementedError("ViewInspector must implement get_operation()!")
|
||||
|
||||
# methods below provided as default implementations for probing inspectors
|
||||
def is_list_view(self):
|
||||
"""Determine whether this view is a list or a detail view. The difference between the two is that
|
||||
detail views depend on a pk/id path parameter. Note that a non-detail view does not necessarily imply a list
|
||||
reponse (:meth:`.has_list_response`), nor are list responses limited to non-detail views.
|
||||
|
||||
For example, one might have a `/topic/<pk>/posts` endpoint which is a detail view that has a list response.
|
||||
|
||||
:rtype: bool"""
|
||||
return is_list_view(self.path, self.method, self.view)
|
||||
|
||||
def has_list_response(self):
|
||||
"""Determine whether this view returns multiple objects. By default this is any non-detail view
|
||||
(see :meth:`.is_list_view`) whose request method is one of :attr:`.implicit_list_response_methods`.
|
||||
|
||||
:rtype: bool
|
||||
"""
|
||||
return self.is_list_view() and (self.method.upper() in self.implicit_list_response_methods)
|
||||
|
||||
def should_filter(self):
|
||||
"""Determine whether filter backend parameters should be included for this request.
|
||||
|
||||
:rtype: bool
|
||||
"""
|
||||
if not getattr(self.view, 'filter_backends', None):
|
||||
return False
|
||||
|
||||
if self.method.lower() not in ["get", "delete"]:
|
||||
return False
|
||||
|
||||
return is_list_view(self.path, self.method, self.view)
|
||||
return getattr(self.view, 'filter_backends', None) and self.has_list_response()
|
||||
|
||||
def get_filter_parameters(self):
|
||||
"""Return the parameters added to the view by its filter backends.
|
||||
@@ -408,13 +422,7 @@ class ViewInspector(BaseInspector):
|
||||
|
||||
:rtype: bool
|
||||
"""
|
||||
if not getattr(self.view, 'paginator', None):
|
||||
return False
|
||||
|
||||
if self.method.lower() != 'get':
|
||||
return False
|
||||
|
||||
return is_list_view(self.path, self.method, self.view)
|
||||
return getattr(self.view, 'paginator', None) and self.has_list_response()
|
||||
|
||||
def get_pagination_parameters(self):
|
||||
"""Return the parameters added to the view by its paginator.
|
||||
|
||||
@@ -13,7 +13,9 @@ from rest_framework.settings import api_settings as rest_framework_settings
|
||||
|
||||
from .. import openapi
|
||||
from ..errors import SwaggerGenerationError
|
||||
from ..utils import decimal_as_float, filter_none, get_serializer_class, get_serializer_ref_name
|
||||
from ..utils import (
|
||||
decimal_as_float, field_value_to_representation, filter_none, get_serializer_class, get_serializer_ref_name
|
||||
)
|
||||
from .base import FieldInspector, NotHandled, SerializerInspector, call_view_method
|
||||
|
||||
try:
|
||||
@@ -635,7 +637,14 @@ class ChoiceFieldInspector(FieldInspector):
|
||||
|
||||
if isinstance(field, serializers.ChoiceField):
|
||||
enum_type = openapi.TYPE_STRING
|
||||
enum_values = list(field.choices.keys())
|
||||
enum_values = []
|
||||
for choice in field.choices.keys():
|
||||
if isinstance(field, serializers.MultipleChoiceField):
|
||||
choice = field_value_to_representation(field, [choice])[0]
|
||||
else:
|
||||
choice = field_value_to_representation(field, choice)
|
||||
|
||||
enum_values.append(choice)
|
||||
|
||||
# for ModelSerializer, try to infer the type from the associated model field
|
||||
serializer = get_parent_serializer(field)
|
||||
|
||||
@@ -208,7 +208,7 @@ class SwaggerAutoSchema(ViewInspector):
|
||||
default_schema = self.serializer_to_schema(default_schema) or ''
|
||||
|
||||
if default_schema:
|
||||
if is_list_view(self.path, self.method, self.view) and self.method.lower() == 'get':
|
||||
if self.has_list_response():
|
||||
default_schema = openapi.Schema(type=openapi.TYPE_ARRAY, items=default_schema)
|
||||
if self.should_page():
|
||||
default_schema = self.get_paginated_response(default_schema) or default_schema
|
||||
|
||||
+33
-32
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+25
-7
@@ -2,11 +2,12 @@ import inspect
|
||||
import logging
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
from decimal import Decimal
|
||||
|
||||
from django.db import models
|
||||
from django.utils.encoding import force_text
|
||||
from rest_framework import serializers, status
|
||||
from rest_framework.mixins import DestroyModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||
from rest_framework.parsers import FileUploadParser
|
||||
from rest_framework.request import is_form_media_type
|
||||
from rest_framework.settings import api_settings as rest_framework_settings
|
||||
@@ -226,6 +227,9 @@ def is_list_view(path, method, view):
|
||||
# a detail action is surely not a list route
|
||||
return False
|
||||
|
||||
if isinstance(view, ListModelMixin):
|
||||
return True
|
||||
|
||||
# for GenericAPIView, if it's a detail view it can't also be a list view
|
||||
if isinstance(view, (RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin)):
|
||||
return False
|
||||
@@ -437,6 +441,25 @@ def force_real_str(s, encoding='utf-8', strings_only=False, errors='strict'):
|
||||
return s
|
||||
|
||||
|
||||
def field_value_to_representation(field, value):
|
||||
"""Convert a python value related to a field (default, choices, etc.) into its OpenAPI-compatible representation.
|
||||
|
||||
:param serializers.Field field: field associated with the value
|
||||
:param object value: value
|
||||
:return: the converted value
|
||||
"""
|
||||
value = field.to_representation(value)
|
||||
if isinstance(value, Decimal):
|
||||
if decimal_as_float(field):
|
||||
value = float(value)
|
||||
else:
|
||||
value = str(value)
|
||||
|
||||
# JSON roundtrip ensures that the value is valid JSON;
|
||||
# for example, sets and tuples get transformed into lists
|
||||
return json.loads(json.dumps(value, cls=encoders.JSONEncoder))
|
||||
|
||||
|
||||
def get_field_default(field):
|
||||
"""
|
||||
Get the default value for a field, converted to a JSON-compatible value while properly handling callables.
|
||||
@@ -458,12 +481,7 @@ def get_field_default(field):
|
||||
|
||||
if default is not serializers.empty and default is not None:
|
||||
try:
|
||||
default = field.to_representation(default)
|
||||
# JSON roundtrip ensures that the value is valid JSON;
|
||||
# for example, sets and tuples get transformed into lists
|
||||
default = json.loads(json.dumps(default, cls=encoders.JSONEncoder))
|
||||
if decimal_as_float(field):
|
||||
default = float(default)
|
||||
default = field_value_to_representation(field, default)
|
||||
except Exception: # pragma: no cover
|
||||
logger.warning("'default' on schema for %s will not be set because "
|
||||
"to_representation raised an exception", field, exc_info=True)
|
||||
|
||||
@@ -7,7 +7,7 @@ from rest_framework import viewsets
|
||||
# noinspection PyDeprecation
|
||||
from rest_framework.filters import OrderingFilter
|
||||
from rest_framework.pagination import LimitOffsetPagination
|
||||
from rest_framework.parsers import MultiPartParser, FileUploadParser
|
||||
from rest_framework.parsers import FileUploadParser, MultiPartParser
|
||||
from rest_framework.response import Response
|
||||
|
||||
from articles import serializers
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 2.1.7 on 2019-03-16 14:06
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('snippets', '0002_auto_20181219_1016'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SnippetViewer',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('snippet', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='viewers', to='snippets.Snippet')),
|
||||
('viewer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='snippet_views', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -18,3 +18,8 @@ class Snippet(models.Model):
|
||||
|
||||
class Meta:
|
||||
ordering = ('created',)
|
||||
|
||||
|
||||
class SnippetViewer(models.Model):
|
||||
snippet = models.ForeignKey(Snippet, on_delete=models.CASCADE, related_name='viewers')
|
||||
viewer = models.ForeignKey('auth.User', related_name='snippet_views', on_delete=models.CASCADE)
|
||||
|
||||
@@ -4,7 +4,7 @@ from django.contrib.auth import get_user_model
|
||||
from rest_framework import serializers
|
||||
from rest_framework.compat import MaxLengthValidator, MinValueValidator
|
||||
|
||||
from snippets.models import LANGUAGE_CHOICES, STYLE_CHOICES, Snippet
|
||||
from snippets.models import LANGUAGE_CHOICES, STYLE_CHOICES, Snippet, SnippetViewer
|
||||
|
||||
|
||||
class LanguageSerializer(serializers.Serializer):
|
||||
@@ -100,3 +100,9 @@ class SnippetSerializer(serializers.Serializer):
|
||||
instance.style = validated_data.get('style', instance.style)
|
||||
instance.save()
|
||||
return instance
|
||||
|
||||
|
||||
class SnippetViewerSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SnippetViewer
|
||||
fields = '__all__'
|
||||
|
||||
@@ -8,10 +8,13 @@ if django.VERSION[:2] >= (2, 0):
|
||||
urlpatterns = [
|
||||
path('', views.SnippetList.as_view()),
|
||||
path('<int:pk>/', views.SnippetDetail.as_view()),
|
||||
path('views/<int:snippet_pk>/', views.SnippetViewerList.as_view()),
|
||||
]
|
||||
else:
|
||||
from django.conf.urls import url
|
||||
|
||||
urlpatterns = [
|
||||
url('^$', views.SnippetList.as_view()),
|
||||
url(r'^(?P<pk>\d+)/$', views.SnippetDetail.as_view()),
|
||||
url(r'^views/(?P<snippet_pk>\d+)/$', views.SnippetViewerList.as_view()),
|
||||
]
|
||||
|
||||
@@ -2,13 +2,15 @@ from djangorestframework_camel_case.parser import CamelCaseJSONParser
|
||||
from djangorestframework_camel_case.render import CamelCaseJSONRenderer
|
||||
from inflection import camelize
|
||||
from rest_framework import generics, status
|
||||
from rest_framework.parsers import FormParser, FileUploadParser
|
||||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from rest_framework.parsers import FileUploadParser, FormParser
|
||||
|
||||
from drf_yasg import openapi
|
||||
from drf_yasg.inspectors import SwaggerAutoSchema
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from snippets.models import Snippet
|
||||
from snippets.serializers import SnippetSerializer
|
||||
from snippets.models import Snippet, SnippetViewer
|
||||
from snippets.serializers import SnippetSerializer, SnippetViewerSerializer
|
||||
|
||||
|
||||
class CamelCaseOperationIDAutoSchema(SwaggerAutoSchema):
|
||||
@@ -93,3 +95,31 @@ class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
def delete(self, request, *args, **kwargs):
|
||||
"""delete method docstring"""
|
||||
return super(SnippetDetail, self).patch(request, *args, **kwargs)
|
||||
|
||||
|
||||
class SnippetViewerList(generics.ListAPIView):
|
||||
"""SnippetViewerList classdoc"""
|
||||
serializer_class = SnippetViewerSerializer
|
||||
pagination_class = PageNumberPagination
|
||||
|
||||
parser_classes = (FormParser, CamelCaseJSONParser, FileUploadParser)
|
||||
renderer_classes = (CamelCaseJSONRenderer,)
|
||||
swagger_schema = CamelCaseOperationIDAutoSchema
|
||||
lookup_url_kwarg = 'snippet_pk'
|
||||
|
||||
def get_object(self):
|
||||
queryset = Snippet.objects.all()
|
||||
|
||||
# Perform the lookup filtering.
|
||||
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
|
||||
|
||||
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
|
||||
obj = get_object_or_404(queryset, **filter_kwargs)
|
||||
|
||||
# May raise a permission denied
|
||||
self.check_object_permissions(self.request, obj)
|
||||
|
||||
return obj
|
||||
|
||||
def get_queryset(self):
|
||||
return SnippetViewer.objects.filter(snippet=self.get_object())
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Generated by Django 2.1.5 on 2019-04-01 00:28
|
||||
|
||||
from decimal import Decimal
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('todo', '0002_todotree'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Pack',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('size_code', models.DecimalField(choices=[(Decimal('50'), '5x10'), (Decimal('100'), '10x10'), (Decimal('200'), '10x20')], decimal_places=3, default=Decimal('200'), max_digits=7)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,3 +1,5 @@
|
||||
from decimal import Decimal
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
@@ -18,3 +20,19 @@ class TodoYetAnother(models.Model):
|
||||
class TodoTree(models.Model):
|
||||
parent = models.ForeignKey('self', on_delete=models.CASCADE, related_name='children', null=True)
|
||||
title = models.CharField(max_length=50)
|
||||
|
||||
|
||||
class Pack(models.Model):
|
||||
SIZE_10x20 = Decimal(200.000)
|
||||
SIZE_10x10 = Decimal(100.000)
|
||||
SIZE_5x10 = Decimal(50.000)
|
||||
|
||||
size_code_choices = (
|
||||
(SIZE_5x10, '5x10'),
|
||||
(SIZE_10x10, '10x10'),
|
||||
(SIZE_10x20, '10x20'),
|
||||
)
|
||||
size_code = models.DecimalField(max_digits=7,
|
||||
decimal_places=3,
|
||||
choices=size_code_choices,
|
||||
default=SIZE_10x20)
|
||||
|
||||
@@ -4,7 +4,7 @@ from django.utils import timezone
|
||||
from rest_framework import serializers
|
||||
from rest_framework_recursive.fields import RecursiveField
|
||||
|
||||
from .models import Todo, TodoAnother, TodoTree, TodoYetAnother
|
||||
from .models import Pack, Todo, TodoAnother, TodoTree, TodoYetAnother
|
||||
|
||||
|
||||
class TodoSerializer(serializers.ModelSerializer):
|
||||
@@ -57,3 +57,14 @@ class TodoRecursiveSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = TodoTree
|
||||
fields = ('id', 'title', 'parent', 'parent_id')
|
||||
|
||||
|
||||
class HarvestSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Pack
|
||||
fields = (
|
||||
'size_code',
|
||||
)
|
||||
read_only_fields = (
|
||||
'size_code',
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@ router.register(r'another', views.TodoAnotherViewSet)
|
||||
router.register(r'yetanother', views.TodoYetAnotherViewSet)
|
||||
router.register(r'tree', views.TodoTreeView)
|
||||
router.register(r'recursive', views.TodoRecursiveView)
|
||||
router.register(r'harvest', views.HarvestViewSet)
|
||||
|
||||
urlpatterns = router.urls
|
||||
|
||||
|
||||
+18
-3
@@ -1,11 +1,13 @@
|
||||
from rest_framework import viewsets
|
||||
from rest_framework import mixins, permissions, viewsets
|
||||
from rest_framework.authentication import TokenAuthentication
|
||||
from rest_framework.generics import RetrieveAPIView
|
||||
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
|
||||
from .models import Todo, TodoAnother, TodoTree, TodoYetAnother
|
||||
from .models import Pack, Todo, TodoAnother, TodoTree, TodoYetAnother
|
||||
from .serializer import (
|
||||
TodoAnotherSerializer, TodoRecursiveSerializer, TodoSerializer, TodoTreeSerializer, TodoYetAnotherSerializer
|
||||
HarvestSerializer, TodoAnotherSerializer, TodoRecursiveSerializer, TodoSerializer, TodoTreeSerializer,
|
||||
TodoYetAnotherSerializer
|
||||
)
|
||||
|
||||
|
||||
@@ -75,3 +77,16 @@ class TodoRecursiveView(viewsets.ModelViewSet):
|
||||
@swagger_auto_schema(responses={200: TodoRecursiveSerializer(many=True)})
|
||||
def list(self, request, *args, **kwargs):
|
||||
return super(TodoRecursiveView, self).list(request, *args, **kwargs)
|
||||
|
||||
|
||||
class HarvestViewSet(mixins.ListModelMixin,
|
||||
mixins.UpdateModelMixin,
|
||||
viewsets.GenericViewSet):
|
||||
|
||||
queryset = Pack.objects.all()
|
||||
serializer_class = HarvestSerializer
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
authentication_classes = [TokenAuthentication]
|
||||
|
||||
def perform_update(self, serializer):
|
||||
pass
|
||||
|
||||
@@ -440,6 +440,46 @@ paths:
|
||||
tags:
|
||||
- snippets
|
||||
parameters: []
|
||||
/snippets/views/{snippet_pk}/:
|
||||
get:
|
||||
operationId: snippetsViewsRead
|
||||
description: SnippetViewerList classdoc
|
||||
parameters:
|
||||
- name: page
|
||||
in: query
|
||||
description: A page number within the paginated result set.
|
||||
required: false
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
required:
|
||||
- count
|
||||
- results
|
||||
type: object
|
||||
properties:
|
||||
count:
|
||||
type: integer
|
||||
next:
|
||||
type: string
|
||||
format: uri
|
||||
x-nullable: true
|
||||
previous:
|
||||
type: string
|
||||
format: uri
|
||||
x-nullable: true
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/SnippetViewer'
|
||||
tags:
|
||||
- snippets
|
||||
parameters:
|
||||
- name: snippet_pk
|
||||
in: path
|
||||
required: true
|
||||
type: string
|
||||
/snippets/{id}/:
|
||||
get:
|
||||
operationId: snippetsRead
|
||||
@@ -552,6 +592,60 @@ paths:
|
||||
description: A unique integer value identifying this todo another.
|
||||
required: true
|
||||
type: integer
|
||||
/todo/harvest/:
|
||||
get:
|
||||
operationId: todo_harvest_list
|
||||
description: ''
|
||||
parameters: []
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Harvest'
|
||||
tags:
|
||||
- todo
|
||||
parameters: []
|
||||
/todo/harvest/{id}/:
|
||||
put:
|
||||
operationId: todo_harvest_update
|
||||
description: ''
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Harvest'
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/Harvest'
|
||||
tags:
|
||||
- todo
|
||||
patch:
|
||||
operationId: todo_harvest_partial_update
|
||||
description: ''
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Harvest'
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/Harvest'
|
||||
tags:
|
||||
- todo
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: A unique integer value identifying this pack.
|
||||
required: true
|
||||
type: integer
|
||||
/todo/recursive/:
|
||||
get:
|
||||
operationId: todo_recursive_list
|
||||
@@ -1590,6 +1684,22 @@ definitions:
|
||||
format: decimal
|
||||
default: 0.0
|
||||
minimum: 0.0
|
||||
SnippetViewer:
|
||||
required:
|
||||
- snippet
|
||||
- viewer
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
title: ID
|
||||
type: integer
|
||||
readOnly: true
|
||||
snippet:
|
||||
title: Snippet
|
||||
type: integer
|
||||
viewer:
|
||||
title: Viewer
|
||||
type: integer
|
||||
Todo:
|
||||
required:
|
||||
- title
|
||||
@@ -1613,6 +1723,17 @@ definitions:
|
||||
minLength: 1
|
||||
todo:
|
||||
$ref: '#/definitions/Todo'
|
||||
Harvest:
|
||||
type: object
|
||||
properties:
|
||||
size_code:
|
||||
title: Size code
|
||||
type: string
|
||||
enum:
|
||||
- '50'
|
||||
- '100'
|
||||
- '200'
|
||||
readOnly: true
|
||||
TodoRecursive:
|
||||
required:
|
||||
- title
|
||||
|
||||
Reference in New Issue
Block a user