Search code examples
djangodjango-rest-frameworkdjango-viewsdjango-rest-swagger

django-rest-swagger UI doesn't have form for POST request body (function based view)


I have this function-based view with django-rest-swagger decorated. However, I can't find place in UI that allow me to post the payload (request.body).

I saw a couple solutions about doing it with class-based view, but I was wondering if there is a way to do it with function-based view.

Thank you in advance!

@renderer_classes([JSONRender])
@api_view(['POST'])
def some_method(request):
    body = json.loads(request.body)
    return JsonResponse({'status': 'ok'})

enter image description here


Solution

  • I am gonna answer my question since the django-rest-swagger was deprecated in June 2019 and I just found out 2 feasible solutions.

    First one will change the UI globally.

    In ping.views (or any other location you wish) add following class.

    from rest_framework.schema import AutoSchema
    
    class CustomSchema(AutoSchema):
        def __init__(self):
            super(CustomSchema, self).__init__()
        def get_manual_fields(self, path, method):
            extra_fields = [
                coreapi.Field('command', required=True, location='form', schema=String(), description='', type='', example='',
                coreapi.Field('params', required=False, location='form', schema=String(), description='', type='', example='',
            ]
            manual_fields = super().get_manual_fields(path, method)
            return manual_fields + extra_fields
    

    Add following settings in settings.py of your Django project.

    REST_FRAMEWORK = {
        # Corresponding path to where you added the class
        'DEFAULT_SCHEMA_CLASS': 'ping.views.CustomSchema', 
    }
    

    Second solution can be applied on a per-view basis. You may check here for official guide

    Use @schema from rest_framework.decorators.schema to overwrite DEFAULT_SCHEMA_CLASS.

    @api_view(['POST'])
    @schema(CustomSchema())
    def your_view(request):
        print(request.body)
        return JsonResponse({'task_status': 200'})
    

    Basically, the idea is to overwrite DEFAULT_SCHEMA_CLASS. The word schema is the term that they used to refer to swagger UI for each view in rest_framework.

    When you use @api_view() to decorate your function-based view, it will assign your function an attribute schema with value APIView.schema from rest_framework.views.APIView.

    rest_framework.views.APIView will in further call DefaultSchema() to load the DEFAULT_SCHEMA_CLASS from your REST_FRAMEWORK configuration in settings.py.

    Without other specifying, DEFAULT_SCHEMA_CLASS is rest_framework.schemas.openapi.AutoSchema by this official announcement. You might want to change it to rest_framework.schemas.coreapi.AutoSchema since it is the one that compatible with django_rest_swagger.


    Hope this tutorial helps people who use django-rest-swagger (2.2.0) with function-based views for their Django project.

    Please leave comments if there are anything I can help on this issue.