title: Django Rest Framework custom POST URL endpoints with defined parameter (request.POST) with Swagger or other doc
body: <p>previously in Django 1.11, I'ved defined Django REST API in this way:</p>
  <p>in url.py</p>
  <pre><code>url(r'^api/test_token$', api.test_token, name='test_token'),
  </code></pre>
  <p>in api.py</p>
  <pre><code>@api_view(['POST'])
  def test_token(request):
      # ----- YAML below for Swagger -----
      &quot;&quot;&quot;
      description: test_token
      parameters:
        - name: token
          type: string
          required: true
          location: form       
      &quot;&quot;&quot;
      token = request.POST['token']
  
      return Response(&quot;test_token success&quot;, status=status.HTTP_200_OK)
  </code></pre>
  <p>Now that I am migrating to Django 3.1.5, I'd like to know how the above can be achieved in the same way with Django Rest Framework (DRF). In the above particular case, it is POST API &quot;test_token&quot; that takes in one parameter. And generate API documentation like swagger/redoc (that can be used for testing the API)</p>
  <p><a href="https://i.imgur.com/thUCVFA.png" rel="nofollow noreferrer"><img src="https://i.imgur.com/thUCVFA.png" alt="enter image description here" /></a></p>
  <p>Some Notes:</p>
  <ul>
  <li>its also noted here that django-rest-swagger was deprecated in June 2019 <a href="https://stackoverflow.com/questions/58461938/django-rest-swagger-ui-doesnt-have-form-for-post-request-body-function-based-v">django-rest-swagger UI doesn&#39;t have form for POST request body (function based view)</a></li>
  <li>its important to note, its using request.POST (form data) for the parameters <a href="https://www.django-rest-framework.org/tutorial/2-requests-and-responses/" rel="nofollow noreferrer">https://www.django-rest-framework.org/tutorial/2-requests-and-responses/</a></li>
  <li>in Django 1.11.x I was using this swagger_schema.py - <a href="https://gist.github.com/axilaris/b7152215a76f6f1f5ffca0436991328d" rel="nofollow noreferrer">https://gist.github.com/axilaris/b7152215a76f6f1f5ffca0436991328d</a></li>
  </ul>
  <p>How can I implement this on Django 3.x ? (as in the title: Django Rest Framework custom POST URL endpoints with defined parameter with Swagger or other doc)</p>
  <p><strong>UPDATE:</strong></p>
  <p>I think there is some form of solution from here:
  <a href="https://github.com/tfranzel/drf-spectacular/issues/279" rel="nofollow noreferrer">https://github.com/tfranzel/drf-spectacular/issues/279</a></p>
  <p>As I have a whole lot of APIs that uses @api_view, the changes docstring
  to the decorator @extend_schema may be simplest migration path. I hope someone can provide guidance on url.py to the conversion using @extend_schema. This is to get the url end points and swagger implemented. Thanks.</p>
  <p>This is closest I'ved got with drf-spectacular however</p>
  <pre><code>@extend_schema( 
   parameters=[OpenApiParameter( 
       name='token', 
       type={'type': 'string'}, 
       location=OpenApiParameter.QUERY, 
       required=False, 
       style='form', 
       explode=False, 
   )], 
   responses=OpenApiTypes.OBJECT, 
  ) 
  @api_view(['POST'])
  def test_api(request):
      # ----- YAML below for Swagger -----
      &quot;&quot;&quot;
      description: test_api
      parameters:
        - name: token
          type: string
          required: true
          location: form       
      &quot;&quot;&quot;
      token = request.POST['token']
      
      return Response(&quot;success test_api:&quot; + token, status=status.HTTP_200_OK)
  </code></pre>
  <p>its giving this (which is incorrect), notice the token query</p>
  <pre><code>curl -X POST &quot;http://localhost:8000/api/test_token/?token=hello&quot; -H  &quot;accept: application/json&quot; -H  &quot;X-CSRFToken: JyPOSAQx04LK0aM8IUgUmkruALSNwRbeYDzUHBhCjtXafC3tnHRFsxvyg5SgMLhI&quot; -d &quot;&quot;
  </code></pre>
  <p>instead of a POST input param (how to get this ?)</p>
  <pre><code>curl -X POST --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json' --header 'X-CSRFToken: aExHCSwrRyStDiOhkk8Mztfth2sqonhTkUFaJbnXSFKXCynqzDQEzcRCAufYv6MC' -d 'token=hello' 'http://localhost:8000/api/test_token/
  </code></pre>
  <p><strong>THE SOLUTION:</strong></p>
  <p>url.py</p>
  <pre><code>from drf_yasg.utils import swagger_auto_schema 
  
  from rest_framework.response import Response
  from rest_framework import status
  
  from rest_framework.decorators import parser_classes
  from rest_framework.parsers import FormParser
  
  token = openapi.Parameter('token', openapi.IN_FORM, type=openapi.TYPE_STRING, required=True)
  something = openapi.Parameter('something', openapi.IN_FORM, type=openapi.TYPE_INTEGER, required=False)
  @swagger_auto_schema(
      method=&quot;post&quot;,
      manual_parameters=[token, something],
      operation_id=&quot;token_api&quot;
  )
  @api_view(['POST'])
  # this is optional and insures that the view gets formdata
  @parser_classes([FormParser])
  def token_api(request):
      token = request.POST['token']
      something = request.POST['something']
      
      return Response(&quot;success test_api:&quot; + token + something, status=status.HTTP_200_OK)
  
  
  schema_view = get_schema_view(
     openapi.Info(
        title=&quot;Snippets API&quot;,
        default_version='v1',
        description=&quot;Test description&quot;,
        terms_of_service=&quot;https://www.google.com/policies/terms/&quot;,
        contact=openapi.Contact(email=&quot;contact@snippets.local&quot;),
        license=openapi.License(name=&quot;BSD License&quot;),
     ),
     public=True,
     permission_classes=[permissions.AllowAny],
  )
  
  
  urlpatterns = [
      
      path('token_api', token_api, name='token_api'),
  
      path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
      
  ] + required_urlpatterns
  </code></pre>