Самостоятельное документирование представлений модели Django Drf
Надеялся создать настраиваемый ModelViewSet для наследования, который создает обобщенную информацию о различных маршрутах CRUD. Прямо сейчас мы должны перезаписать методы, которые не нуждаются в изменении. Некоторые представления требуют перезаписи почти каждого метода или записи представлений функций и т. Д., Но другие могут иметь 1 или 0 изменений только из ModelViewSet. Использование эффектного django делает модели огромными и скрывает соответствующую логику между беспорядком текста.
Я надеюсь, что есть более умный / лучший способ сделать это?
Пример
Учитывая простую модель NameTag, которая поставляется в тестовом API:
models.py
from django.db import models
class NameTag(models.Model):
name = models.CharField(max_length=50)
serializers.py
from rest_framework import serializers
from .models import NameTag
class NameTagSerializer(serializers.Serializer):
class Meta:
model = NameTag
api.py
from rest_framework import viewsets
from .models import NameTag
from .serializers import NameTagSerializer
class NameTagViewset(viewsets.ModelViewSet):
serializer_class = NameTagSerializer
model = NameTag
при использовании extend_schema набор просмотра становится огромным.
документированный_api.py
from drf_spectacular.utils import extend_schema
from rest_framework import serializers, viewsets
class NameTagViewset(viewsets.ModelViewSet):
serializer_class = NameTagSerializer
model = NameTag
@extend_schema(
operation_id='New NameTag',
description='Create a new NameTag',
tags=['NameTags']
)
def create(self, request, *args, **kwargs):
return super().create(request, *args, **kwargs)
@extend_schema(
operation_id='List of NameTags',
description='All NameTags',
tags=['NameTags'],
)
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
@extend_schema(
operation_id='NameTag details',
description='Info about current NameTags',
tags=['NameTags']
)
def retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)
@extend_schema(
operation_id='Update NameTag info',
description='Update info of current NameTag',
tags=['NameTags']
)
def update(self, request, *args, **kwargs):
return super().update(request, *args, **kwargs)
@extend_schema(
operation_id='Partial update NameTag info',
description='Partial update info of current NameTag',
tags=['NameTags']
)
def partial_update(self, request, *args, **kwargs):
return super().update(request, *args, **kwargs)
@extend_schema(
operation_id='Delete NameTag',
description='Delete current NameTag',
tags=['NameTags']
)
def destroy(self, request, *args, **kwargs):
return super().destroy(request, *args, **kwargs)
Это полностью противоречит цели использования ModelViewSet.
Я думал, что напишу класс, который даст общую информацию. Это не оптимальное решение, но я сделал его просто для тестирования. Идея заключалась в том, что вы могли даже перезаписать определенные части документа, не перезаписывая метод, если вы не меняли какую-либо бизнес-логику. номинал:
API_DOCUMENTATION['list']['tags'] += ['TAGS']
документированный_ModelViewSet.py
from drf_spectacular.utils import extend_schema
from rest_framework import viewsets
class documented_viewset(viewsets.ModelViewSet):
API_MODEL = {'name': None, 'tags': [], 'serializer': None}
API_DOCUMENTATION = {
'list': {
'operation_id': f'List of {API_MODEL.get("name")}',
'description': f'List of {API_MODEL.get("name")} instances',
'tags': API_MODEL.get("tags")
},
'retrieve': {
'operation_id': f'{API_MODEL.get("name")} details',
'description': f'Detail info about {API_MODEL.get("name")} by id',
'tags': API_MODEL.get("tags")
},
'update': {
'operation_id': f'Update {API_MODEL.get("name")}',
'description': f'Update {API_MODEL.get("name")} with id',
'tags': API_MODEL.get("tags")
},
'partial_update': {
'operation_id': f'Partial_update {API_MODEL.get("name")}',
'description': f'Partial_update {API_MODEL.get("name")} with id',
'tags': API_MODEL.get("tags")
},
'destroy': {
'operation_id': f'Delete {API_MODEL.get("name")}',
'description': f'Delete {API_MODEL.get("name")} by id',
'tags': API_MODEL.get("tags")
},
'create': {
'operation_id': f'New {API_MODEL.get("name")}',
'description': f'Create new {API_MODEL.get("name")}',
'tags': API_MODEL.get("tags"),
}
}
if API_MODEL.get('serializer'):
API_DOCUMENTATION['create'].update(**{
'request': API_MODEL.get('serializer'),
'responses': {201: API_MODEL.get('serializer')},
})
@extend_schema(**API_DOCUMENTATION.get('list'))
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
@extend_schema(**API_DOCUMENTATION.get('retrieve'))
def retrieve(self, request, pk, *args, **kwargs):
return super().retrieve(request, pk, *args, **kwargs)
@extend_schema(**API_DOCUMENTATION.get('update'))
def update(self, request, pk, *args, **kwargs):
return super().update(request, pk, *args, **kwargs)
@extend_schema(**API_DOCUMENTATION.get('partial_update'))
def partial_update(self, request, pk, *args, **kwargs):
return super().partial_update(request, pk, *args, **kwargs)
@extend_schema(**API_DOCUMENTATION.get('destroy'))
def destroy(self, request, pk, *args, **kwargs):
return super().destroy(request, pk, *args, **kwargs)
@extend_schema(**API_DOCUMENTATION.get('create'))
def create(self, request, *args, **kwargs):
return super().create(request, *args, **kwargs)
но при наследовании от этого используются родительские значения из-за того, как работают декораторы. Хотя о написании настраиваемого декоратора + настраиваемого представления, но тогда это становится слишком сложным, просто чтобы упростить представления приложений ... Есть ли лучший / более разумный способ решить эту проблему?