How to return actions and parameters in OPTIONS request with django rest framework

1.3k views Asked by At

I try to return a list of select options for countries using django-countries and django rest framework. I use JWT_AUTH for the authentication.

When I try a options request:

curl \
  -H "Authentication: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFsYmVydG9fdmVudGEiLCJ1c2VyX2lkIjoyLCJlbWFpbCI6IiIsImV4cCI6MTUwODE2Mzg4Mn0.svxqTThCahSl1Vu27sMjuJyd1PRLk28-Xgn2OKKb5-g"\
  -X OPTIONS \
  -v http://127.0.0.1:8000/api/v1/core/perfilViajeroUserPass/

The response is:

{
 "name":"Perfil Viajero User Pass Create",
 "description":"",
 "renders":["application/json","text/html"],
 "parses":[
           "application/json",
           "application/x-www-form-urlencoded",
           "multipart/form-data"
          ]
}

But I think that it should be something like this by default:

{
"name": "To Do List",
"description": "List existing 'To Do' items, or create a new item.",
"renders": [
    "application/json",
    "text/html"
],
"parses": [
    "application/json",
    "application/x-www-form-urlencoded",
    "multipart/form-data"
],
"actions": {
    "POST": {
        "note": {
            "type": "string",
            "required": false,
            "read_only": false,
            "label": "title",
            "max_length": 100
        }
    }
}

}

Someone could help me? thanks.

4

There are 4 answers

0
Alberto Diaz On BEST ANSWER

I have found the solution.

I change my view class type from APIView to generics.CreateAPIView and know it works. Thank you very much.

3
Linovia On

If you want to change some of the content:

  • name is the view's get_view_name which is the view's name slightly reworked.
  • description is the view's get_view_description which reworks the view's docstring.

Otherwise if you want something more complex, you'll probably want to customize the view's metadata as explained in http://www.django-rest-framework.org/api-guide/metadata/#custom-metadata-classes

1
Samira N On

Adding another answer since I recently ran into the same issue and found it a bit mystifying -- when making an OPTIONS request, Django Rest Framework uses the view's Metadata class to construct a response. The default Metadata class is SimpleMetadata, as mentioned in the docs. However, SimpleMetadata only adds the actions key to the response body if the view in question defines the method get_serializer(). I'm not sure why this is the case, but see here for the relevant code.

rest_framework.generics.GenericAPIView defines a get_serializer() method, so (authenticated) OPTIONS requests made to these views will return a response body with the actions key. But rest_framework.views.APIView does not define this method, so the actions key will always be absent.

If you have to use rest_framework.views.APIView, you could work around this by defining a get_serializer() method on your APIView class. Which feels a little hacky, but I tested it and it works:

class MyView(views.APIView):
    def get_serializer(self):
        return MySerializer()

    def post(self):
        ...
0
Erik Wognsen On

Another reason an OPTIONS response doesn't contain the actions list is if the view doesn't allow the PUT or POST methods.

See SimpleMetadata.determine_actions() in the DRF source rest_framework/metadata.py.