Alberto Diaz
Alberto Diaz

Reputation: 113

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

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.

Upvotes: 1

Views: 1740

Answers (4)

Erik Wognsen
Erik Wognsen

Reputation: 75

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.

Upvotes: 0

Samira N
Samira N

Reputation: 163

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):
        ...

Upvotes: 2

Alberto Diaz
Alberto Diaz

Reputation: 113

I have found the solution.

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

Upvotes: 0

Linovia
Linovia

Reputation: 20976

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

Upvotes: 1

Related Questions