mirror of
https://github.com/wger-project/wger.git
synced 2026-02-18 00:17:51 +01:00
Fix many openAPI schema errors
This commit is contained in:
@@ -26,11 +26,22 @@ from django.views.decorators.cache import cache_page
|
||||
|
||||
# Third Party
|
||||
from django_email_verification import send_email
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import (
|
||||
OpenApiParameter,
|
||||
OpenApiResponse,
|
||||
extend_schema,
|
||||
inline_serializer,
|
||||
)
|
||||
from rest_framework import (
|
||||
status,
|
||||
viewsets,
|
||||
)
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import (
|
||||
BooleanField,
|
||||
CharField,
|
||||
)
|
||||
from rest_framework.permissions import (
|
||||
AllowAny,
|
||||
IsAuthenticated,
|
||||
@@ -87,6 +98,10 @@ class UserProfileViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return UserProfile.objects.none()
|
||||
|
||||
return UserProfile.objects.filter(user=self.request.user)
|
||||
|
||||
def get_owner_objects(self):
|
||||
@@ -158,6 +173,12 @@ class ApplicationVersionView(viewsets.ViewSet):
|
||||
permission_classes = (AllowAny, )
|
||||
|
||||
@staticmethod
|
||||
@extend_schema(
|
||||
parameters=[],
|
||||
responses={
|
||||
200: OpenApiTypes.STR,
|
||||
},
|
||||
)
|
||||
def get(request):
|
||||
return Response(get_version())
|
||||
|
||||
@@ -169,6 +190,26 @@ class PermissionView(viewsets.ViewSet):
|
||||
permission_classes = (AllowAny, )
|
||||
|
||||
@staticmethod
|
||||
@extend_schema(
|
||||
parameters=[
|
||||
OpenApiParameter(
|
||||
'permission',
|
||||
OpenApiTypes.STR,
|
||||
OpenApiParameter.QUERY,
|
||||
description='The name of the django permission such as "exercises.change_muscle"',
|
||||
),
|
||||
],
|
||||
responses={
|
||||
201:
|
||||
inline_serializer(name='PermissionResponse', fields={
|
||||
'result': BooleanField(),
|
||||
}),
|
||||
400:
|
||||
OpenApiResponse(
|
||||
description="Please pass a permission name in the 'permission' parameter"
|
||||
),
|
||||
},
|
||||
)
|
||||
def get(request):
|
||||
permission = request.query_params.get('permission')
|
||||
|
||||
@@ -191,6 +232,12 @@ class RequiredApplicationVersionView(viewsets.ViewSet):
|
||||
permission_classes = (AllowAny, )
|
||||
|
||||
@staticmethod
|
||||
@extend_schema(
|
||||
parameters=[],
|
||||
responses={
|
||||
200: OpenApiTypes.STR,
|
||||
},
|
||||
)
|
||||
def get(request):
|
||||
return Response(get_version(MIN_APP_VERSION, True))
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ class ExerciseImageSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
ExerciseImage serializer
|
||||
"""
|
||||
author_history = serializers.ListSerializer(child=serializers.CharField())
|
||||
|
||||
class Meta:
|
||||
model = ExerciseImage
|
||||
@@ -105,6 +106,7 @@ class ExerciseVideoSerializer(serializers.ModelSerializer):
|
||||
ExerciseVideo serializer
|
||||
"""
|
||||
exercise_base_uuid = serializers.ReadOnlyField(source='exercise_base.uuid')
|
||||
author_history = serializers.ListSerializer(child=serializers.CharField())
|
||||
|
||||
class Meta:
|
||||
model = ExerciseVideo
|
||||
@@ -193,6 +195,8 @@ class MuscleSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
Muscle serializer
|
||||
"""
|
||||
image_url_main = serializers.CharField()
|
||||
image_url_secondary = serializers.CharField()
|
||||
|
||||
class Meta:
|
||||
model = Muscle
|
||||
@@ -218,6 +222,7 @@ class ExerciseSerializer(serializers.ModelSerializer):
|
||||
muscles_secondary = serializers.PrimaryKeyRelatedField(many=True, queryset=Muscle.objects.all())
|
||||
equipment = serializers.PrimaryKeyRelatedField(many=True, queryset=Equipment.objects.all())
|
||||
variations = serializers.PrimaryKeyRelatedField(many=True, queryset=Variation.objects.all())
|
||||
author_history = serializers.ListSerializer(child=serializers.CharField())
|
||||
|
||||
class Meta:
|
||||
model = Exercise
|
||||
@@ -252,6 +257,7 @@ class ExerciseTranslationBaseInfoSerializer(serializers.ModelSerializer):
|
||||
)
|
||||
aliases = ExerciseInfoAliasSerializer(source='alias_set', many=True, read_only=True)
|
||||
notes = ExerciseCommentSerializer(source='exercisecomment_set', many=True, read_only=True)
|
||||
author_history = serializers.ListSerializer(child=serializers.CharField())
|
||||
|
||||
class Meta:
|
||||
model = Exercise
|
||||
@@ -340,6 +346,7 @@ class ExerciseInfoSerializer(serializers.ModelSerializer):
|
||||
equipment = EquipmentSerializer(many=True, read_only=True)
|
||||
variations = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
|
||||
aliases = ExerciseInfoAliasSerializer(source='alias_set', many=True, read_only=True)
|
||||
author_history = serializers.ListSerializer(child=serializers.CharField())
|
||||
|
||||
class Meta:
|
||||
model = Exercise
|
||||
@@ -380,6 +387,8 @@ class ExerciseBaseInfoSerializer(serializers.ModelSerializer):
|
||||
exercises = ExerciseTranslationBaseInfoSerializer(many=True, read_only=True)
|
||||
videos = ExerciseVideoSerializer(source='exercisevideo_set', many=True, read_only=True)
|
||||
variations = serializers.PrimaryKeyRelatedField(read_only=True)
|
||||
author_history = serializers.ListSerializer(child=serializers.CharField())
|
||||
total_authors_history = serializers.ListSerializer(child=serializers.CharField())
|
||||
|
||||
class Meta:
|
||||
model = ExerciseBase
|
||||
|
||||
@@ -30,6 +30,12 @@ from django.views.decorators.cache import cache_page
|
||||
import bleach
|
||||
from actstream import action as actstream_action
|
||||
from bleach.css_sanitizer import CSSSanitizer
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import (
|
||||
OpenApiParameter,
|
||||
extend_schema,
|
||||
inline_serializer,
|
||||
)
|
||||
from easy_thumbnails.alias import aliases
|
||||
from easy_thumbnails.files import get_thumbnailer
|
||||
from rest_framework import viewsets
|
||||
@@ -37,6 +43,10 @@ from rest_framework.decorators import (
|
||||
action,
|
||||
api_view,
|
||||
)
|
||||
from rest_framework.fields import (
|
||||
CharField,
|
||||
IntegerField,
|
||||
)
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
@@ -257,6 +267,46 @@ class ExerciseViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
return qs
|
||||
|
||||
|
||||
@extend_schema(
|
||||
parameters=[
|
||||
OpenApiParameter(
|
||||
'term',
|
||||
OpenApiTypes.STR,
|
||||
OpenApiParameter.QUERY,
|
||||
description='The name of the exercise to search"',
|
||||
required=True,
|
||||
),
|
||||
OpenApiParameter(
|
||||
'language',
|
||||
OpenApiTypes.STR,
|
||||
OpenApiParameter.QUERY,
|
||||
description='Comma separated list of language codes to search',
|
||||
required=True,
|
||||
),
|
||||
],
|
||||
responses={
|
||||
200:
|
||||
inline_serializer(
|
||||
name='ExerciseSearchResponse',
|
||||
fields={
|
||||
'value':
|
||||
CharField(),
|
||||
'data':
|
||||
inline_serializer(
|
||||
name='ExerciseSearchItemResponse',
|
||||
fields={
|
||||
'id': IntegerField(),
|
||||
'base_id': IntegerField(),
|
||||
'name': CharField(),
|
||||
'category': CharField(),
|
||||
'image': CharField(),
|
||||
'image_thumbnail': CharField()
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
@api_view(['GET'])
|
||||
def search(request):
|
||||
"""
|
||||
|
||||
@@ -34,7 +34,7 @@ from wger.gallery.models import Image
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ImageViewSet(viewsets.ModelViewSet):
|
||||
class GalleryImageViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
API endpoint for gallery image
|
||||
"""
|
||||
@@ -53,6 +53,10 @@ class ImageViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Image.objects.none()
|
||||
|
||||
return Image.objects.filter(user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
|
||||
@@ -72,6 +72,10 @@ class WorkoutViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Workout.objects.none()
|
||||
|
||||
return Workout.objects.filter(user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
@@ -132,6 +136,10 @@ class UserWorkoutTemplateViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Workout.objects.none()
|
||||
|
||||
return Workout.templates.filter(user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
@@ -189,6 +197,7 @@ class WorkoutSessionViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
API endpoint for workout sessions objects
|
||||
"""
|
||||
|
||||
serializer_class = WorkoutSessionSerializer
|
||||
is_private = True
|
||||
ordering_fields = '__all__'
|
||||
@@ -205,6 +214,11 @@ class WorkoutSessionViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return WorkoutSession.objects.none()
|
||||
|
||||
return WorkoutSession.objects.filter(user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
@@ -238,6 +252,10 @@ class ScheduleStepViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return ScheduleStep.objects.none()
|
||||
|
||||
return ScheduleStep.objects.filter(schedule__user=self.request.user)
|
||||
|
||||
def get_owner_objects(self):
|
||||
@@ -265,6 +283,10 @@ class ScheduleViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Schedule.objects.none()
|
||||
|
||||
return Schedule.objects.filter(user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
@@ -291,6 +313,10 @@ class DayViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Day.objects.none()
|
||||
|
||||
return Day.objects.filter(training__user=self.request.user)
|
||||
|
||||
def get_owner_objects(self):
|
||||
@@ -317,6 +343,10 @@ class SetViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Set.objects.none()
|
||||
|
||||
return Set.objects.filter(exerciseday__training__user=self.request.user)
|
||||
|
||||
def get_owner_objects(self):
|
||||
@@ -363,6 +393,10 @@ class SettingViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Setting.objects.none()
|
||||
|
||||
return Setting.objects.filter(set__exerciseday__training__user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
@@ -397,6 +431,9 @@ class WorkoutLogViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return WorkoutLog.objects.none()
|
||||
|
||||
return WorkoutLog.objects.filter(user=self.request.user)
|
||||
|
||||
|
||||
@@ -51,6 +51,10 @@ class CategoryViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Category.objects.none()
|
||||
|
||||
return Category.objects.filter(user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
@@ -80,4 +84,8 @@ class MeasurementViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Measurement.objects.none()
|
||||
|
||||
return Measurement.objects.filter(category__user=self.request.user)
|
||||
|
||||
@@ -74,7 +74,7 @@ class WeightUnitSerializer(serializers.ModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class ImageSerializer(serializers.ModelSerializer):
|
||||
class IngredientImageSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
Image serializer
|
||||
"""
|
||||
@@ -213,7 +213,7 @@ class MealItemInfoSerializer(serializers.ModelSerializer):
|
||||
ingredient_obj = IngredientInfoSerializer(source='ingredient', read_only=True)
|
||||
weight_unit = serializers.PrimaryKeyRelatedField(read_only=True)
|
||||
weight_unit_obj = IngredientWeightUnitSerializer(source='weight_unit', read_only=True)
|
||||
image = ImageSerializer(source='ingredient.image', read_only=True)
|
||||
image = IngredientImageSerializer(source='ingredient.image', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = MealItem
|
||||
@@ -245,6 +245,20 @@ class MealSerializer(serializers.ModelSerializer):
|
||||
fields = ['id', 'plan', 'order', 'time', 'name']
|
||||
|
||||
|
||||
class NutritionalValuesSerializer(serializers.Serializer):
|
||||
"""
|
||||
Nutritional values serializer
|
||||
"""
|
||||
energy = serializers.FloatField()
|
||||
protein = serializers.FloatField()
|
||||
carbohydrates = serializers.FloatField()
|
||||
carbohydrates_sugar = serializers.FloatField()
|
||||
fat = serializers.FloatField()
|
||||
fat_saturated = serializers.FloatField()
|
||||
fibres = serializers.FloatField()
|
||||
sodium = serializers.FloatField()
|
||||
|
||||
|
||||
class MealInfoSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
Meal info serializer
|
||||
@@ -252,6 +266,7 @@ class MealInfoSerializer(serializers.ModelSerializer):
|
||||
|
||||
meal_items = MealItemInfoSerializer(source='mealitem_set', many=True)
|
||||
plan = serializers.PrimaryKeyRelatedField(read_only=True)
|
||||
get_nutritional_values = NutritionalValuesSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Meal
|
||||
@@ -282,6 +297,7 @@ class NutritionPlanInfoSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
|
||||
meals = MealInfoSerializer(source='meal_set', many=True)
|
||||
get_nutritional_values = NutritionalValuesSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = NutritionPlan
|
||||
|
||||
@@ -25,6 +25,12 @@ from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
|
||||
# Third Party
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import (
|
||||
OpenApiParameter,
|
||||
extend_schema,
|
||||
inline_serializer,
|
||||
)
|
||||
from easy_thumbnails.alias import aliases
|
||||
from easy_thumbnails.files import get_thumbnailer
|
||||
from rest_framework import viewsets
|
||||
@@ -32,11 +38,15 @@ from rest_framework.decorators import (
|
||||
action,
|
||||
api_view,
|
||||
)
|
||||
from rest_framework.fields import (
|
||||
CharField,
|
||||
IntegerField,
|
||||
)
|
||||
from rest_framework.response import Response
|
||||
|
||||
# wger
|
||||
from wger.nutrition.api.serializers import (
|
||||
ImageSerializer,
|
||||
IngredientImageSerializer,
|
||||
IngredientInfoSerializer,
|
||||
IngredientSerializer,
|
||||
IngredientWeightUnitSerializer,
|
||||
@@ -152,6 +162,45 @@ class IngredientInfoViewSet(IngredientViewSet):
|
||||
serializer_class = IngredientInfoSerializer
|
||||
|
||||
|
||||
@extend_schema(
|
||||
parameters=[
|
||||
OpenApiParameter(
|
||||
'term',
|
||||
OpenApiTypes.STR,
|
||||
OpenApiParameter.QUERY,
|
||||
description='The name of the ingredient to search"',
|
||||
required=True,
|
||||
),
|
||||
OpenApiParameter(
|
||||
'language',
|
||||
OpenApiTypes.STR,
|
||||
OpenApiParameter.QUERY,
|
||||
description='Comma separated list of language codes to search',
|
||||
required=True,
|
||||
),
|
||||
],
|
||||
responses={
|
||||
200:
|
||||
inline_serializer(
|
||||
name='IngredientSearchResponse',
|
||||
fields={
|
||||
'value':
|
||||
CharField(),
|
||||
'data':
|
||||
inline_serializer(
|
||||
name='IngredientSearchItemResponse',
|
||||
fields={
|
||||
'id': IntegerField(),
|
||||
'name': CharField(),
|
||||
'category': CharField(),
|
||||
'image': CharField(),
|
||||
'image_thumbnail': CharField()
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
@api_view(['GET'])
|
||||
def search(request):
|
||||
"""
|
||||
@@ -205,7 +254,7 @@ class ImageViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
API endpoint for ingredient images
|
||||
"""
|
||||
queryset = Image.objects.all()
|
||||
serializer_class = ImageSerializer
|
||||
serializer_class = IngredientImageSerializer
|
||||
ordering_fields = '__all__'
|
||||
filterset_fields = ('uuid', 'ingredient_id', 'ingredient__uuid')
|
||||
|
||||
@@ -258,6 +307,10 @@ class NutritionPlanViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return NutritionPlan.objects.none()
|
||||
|
||||
return NutritionPlan.objects.filter(user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
@@ -304,7 +357,7 @@ class NutritionPlanInfoViewSet(NutritionPlanViewSet):
|
||||
Read-only info API endpoint for nutrition plan objects. Returns nested data
|
||||
structures for more easy parsing.
|
||||
"""
|
||||
serializer_class = NutritionPlanInfoSerializer
|
||||
serializer_class = NutritionPlanInfoSerializer(read_only=True)
|
||||
|
||||
|
||||
class MealViewSet(WgerOwnerObjectModelViewSet):
|
||||
@@ -324,6 +377,10 @@ class MealViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return Meal.objects.none()
|
||||
|
||||
return Meal.objects.filter(plan__user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
@@ -365,6 +422,10 @@ class MealItemViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return MealItem.objects.none()
|
||||
|
||||
return MealItem.objects.filter(meal__plan__user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
@@ -406,6 +467,10 @@ class LogItemViewSet(WgerOwnerObjectModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return LogItem.objects.none()
|
||||
|
||||
return LogItem.objects.filter(plan__user=self.request.user)
|
||||
|
||||
def get_owner_objects(self):
|
||||
|
||||
@@ -24,7 +24,6 @@ from datetime import timedelta
|
||||
from wger import get_version
|
||||
from wger.utils.constants import DOWNLOAD_INGREDIENT_WGER
|
||||
|
||||
|
||||
"""
|
||||
This file contains the global settings that don't usually need to be changed.
|
||||
For a full list of options, visit:
|
||||
@@ -175,7 +174,7 @@ TEMPLATES = [
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
],
|
||||
'debug':
|
||||
False
|
||||
False
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -258,7 +257,7 @@ AVAILABLE_LANGUAGES = (
|
||||
LANGUAGE_CODE = 'en'
|
||||
|
||||
# All translation files are in one place
|
||||
LOCALE_PATHS = (os.path.join(SITE_ROOT, 'locale'), )
|
||||
LOCALE_PATHS = (os.path.join(SITE_ROOT, 'locale'),)
|
||||
|
||||
# Primary keys are AutoFields
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
||||
@@ -451,29 +450,16 @@ REST_FRAMEWORK = {
|
||||
'DEFAULT_THROTTLE_RATES': {
|
||||
'login': '10/min'
|
||||
},
|
||||
'DEFAULT_SCHEMA_CLASS':
|
||||
'drf_spectacular.openapi.AutoSchema',
|
||||
}
|
||||
|
||||
# Api docs
|
||||
SPECTACULAR_SETTINGS = {
|
||||
'TITLE': 'wger workout manager',
|
||||
'DESCRIPTION': 'FLOSS self hosted workout and fitness tracker',
|
||||
'VERSION': get_version(),
|
||||
'SERVE_INCLUDE_SCHEMA': False,
|
||||
'SCHEMA_PATH_PREFIX': '/api/v[0-9]',
|
||||
'SWAGGER_UI_DIST': 'SIDECAR',
|
||||
'SWAGGER_UI_FAVICON_HREF': 'SIDECAR',
|
||||
'REDOC_DIST': 'SIDECAR',
|
||||
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
|
||||
}
|
||||
# yapf: enable
|
||||
|
||||
# Api docs
|
||||
SPECTACULAR_SETTINGS = {
|
||||
'TITLE': 'wger workout manager',
|
||||
'DESCRIPTION': 'FLOSS self hosted workout and fitness tracker',
|
||||
'TITLE': 'wger',
|
||||
'DESCRIPTION': 'Self hosted FLOSS workout and fitness tracker',
|
||||
'VERSION': get_version(),
|
||||
'SERVE_INCLUDE_SCHEMA': False,
|
||||
'SERVE_INCLUDE_SCHEMA': True,
|
||||
'SCHEMA_PATH_PREFIX': '/api/v[0-9]',
|
||||
'SWAGGER_UI_DIST': 'SIDECAR',
|
||||
'SWAGGER_UI_FAVICON_HREF': 'SIDECAR',
|
||||
@@ -500,7 +486,7 @@ CORS_URLS_REGEX = r'^/api/.*$'
|
||||
#
|
||||
# Ignore these URLs if they cause 404
|
||||
#
|
||||
IGNORABLE_404_URLS = (re.compile(r'^/favicon\.ico$'), )
|
||||
IGNORABLE_404_URLS = (re.compile(r'^/favicon\.ico$'),)
|
||||
|
||||
#
|
||||
# Password rules
|
||||
|
||||
@@ -9,6 +9,15 @@
|
||||
<p>wger Workout Manager provides a full REST API to all database
|
||||
objects: <a href="/api/v2/" rel="nofollow">https://wger.de/api/v2/</a></p>
|
||||
|
||||
<h3>Documentation</h3>
|
||||
<p>The API is documented with openAPI:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="{% url 'schema' %}">Download schema file</a></li>
|
||||
<li><a href="{% url 'api-swagger-ui' %}">Swagger UI</a></li>
|
||||
<li><a href="{% url 'api-redoc' %}">Redoc</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Authentication</h3>
|
||||
<p>Public endpoints, such as the list of exercises or the
|
||||
@@ -19,7 +28,8 @@
|
||||
<h6>JWT Authentication</h6>
|
||||
|
||||
<p>
|
||||
You can generate access token via <code>/token/</code> endpoint. Send a username and password, and you will get
|
||||
You can generate access token via <code>/token/</code> endpoint. Send a username and
|
||||
password, and you will get
|
||||
the
|
||||
<code>access</code> token which you can use to access the private endpoints.
|
||||
<pre>
|
||||
@@ -36,7 +46,8 @@ curl \
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Additionally, you can send an access token to <code>/token/verify/</code> endpoint to verify that token.</p>
|
||||
<p>Additionally, you can send an access token to <code>/token/verify/</code> endpoint to verify
|
||||
that token.</p>
|
||||
|
||||
<p>When this short-lived access token expires, you can use the longer-lived <code>refresh</code>
|
||||
token to obtain another access token.
|
||||
@@ -55,7 +66,8 @@ curl \
|
||||
|
||||
<p>You should always use HTTPS if possible when communicating with the server.</p>
|
||||
<p>At the moment it is not possible to register via the API.</p>
|
||||
<p><strong>Deprecated: </strong>You can also generate a token via the <code>login</code> endpoint. Send a
|
||||
<p><strong>Deprecated: </strong>You can also generate a token via the <code>login</code>
|
||||
endpoint. Send a
|
||||
username and password, and you will get the user's token or a new one will be
|
||||
generated.</p>
|
||||
|
||||
@@ -197,7 +209,8 @@ curl \
|
||||
<p>
|
||||
You can easily filter all resources by specifying the filter queries in the
|
||||
URL: <code>?<fieldname>=<value></code>, combinations are possible,
|
||||
the filters will be AND-joined: <code>?<f1>=<v1>&<f2>=<v2></code>.
|
||||
the filters will be AND-joined:
|
||||
<code>?<f1>=<v1>&<f2>=<v2></code>.
|
||||
Please note that for boolean values you must pass 'False' or 'True' other
|
||||
values, e.g. 1, 0, false, etc. will be ignored. Like with not filtered queries,
|
||||
your objects will be available under the 'results' key.
|
||||
@@ -449,9 +462,11 @@ curl -H "Authorization: Token 123456..." \
|
||||
{% block sidebar %}
|
||||
<div class="alert alert-info" style="margin-top:1em;">
|
||||
This is also new for us, if you plan on using the API,
|
||||
<a href="https://github.com/wger-project/wger" class="alert-link">we'd love to hear from you</a>.
|
||||
<a href="https://github.com/wger-project/wger" class="alert-link">we'd love to hear from
|
||||
you</a>.
|
||||
</div>
|
||||
|
||||
<p><a href="/api/v2/" class="btn btn-block btn-light" rel="nofollow">Browse the API</a></p>
|
||||
<p><a href="{% url 'core:user:api-key' %}" class="btn btn-block btn-light">Generate API KEY</a></p>
|
||||
<p><a href="{% url 'core:user:api-key' %}" class="btn btn-block btn-light">Generate API KEY</a>
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
||||
13
wger/urls.py
13
wger/urls.py
@@ -53,6 +53,7 @@ from wger.nutrition.sitemap import NutritionSitemap
|
||||
from wger.utils.generic_views import TextTemplateView
|
||||
from wger.weight.api import views as weight_api_views
|
||||
|
||||
|
||||
# admin.autodiscover()
|
||||
|
||||
#
|
||||
@@ -196,7 +197,7 @@ router.register(r'ingredient-image', nutrition_api_views.ImageViewSet, basename=
|
||||
router.register(r'weightentry', weight_api_views.WeightEntryViewSet, basename='weightentry')
|
||||
|
||||
# Gallery app
|
||||
router.register(r'gallery', gallery_api_views.ImageViewSet, basename='gallery')
|
||||
router.register(r'gallery', gallery_api_views.GalleryImageViewSet, basename='gallery')
|
||||
|
||||
# Measurements app
|
||||
router.register(
|
||||
@@ -288,15 +289,9 @@ urlpatterns += [
|
||||
name='schema',
|
||||
),
|
||||
path(
|
||||
'api/schema/swagger-ui/',
|
||||
SpectacularSwaggerView.as_view(url_name='schema'),
|
||||
name='swagger-ui'
|
||||
),
|
||||
path(
|
||||
'api/schema/redoc/',
|
||||
SpectacularRedocView.as_view(url_name='schema'),
|
||||
name='redoc'
|
||||
'api/schema/ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='api-swagger-ui'
|
||||
),
|
||||
path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='api-redoc'),
|
||||
]
|
||||
|
||||
#
|
||||
|
||||
@@ -37,6 +37,10 @@ class WeightEntryViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
"""
|
||||
# REST API generation
|
||||
if getattr(self, "swagger_fake_view", False):
|
||||
return WeightEntry.objects.none()
|
||||
|
||||
return WeightEntry.objects.filter(user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
|
||||
Reference in New Issue
Block a user