How to document response schema for Django REST Framework documentaion? - django

I'm documenting a custom endpoint using default DRF documentation API. The output of the endpoint is quite complex and I need a pretty way to display it to the frontend-developers in documentation API. Current solution is to use method's docstring which is not that pretty.
There is a clean way to describe input parameters using schema, but I'm unable to find examples to describe schema for the output.
There is screenshot in the official documentation that indicates that it is possible (note a response schema at the picture), but unfortunately no example.

I was looking for the same functionality but it seems like most of this response stuff is auto-generated with little control over it. E.g., my setup kept insisting that all my POSTs must return a 201 and no way to specify a custom response body, just some object that it decided this POST is creating.
Ended up using drf-yasg instead, it was super-easy to get started and specify responses, e.g.:
user_response = openapi.Response('response description', UserSerializer)

Related

is there a way to provide custom names for my drf-yasg endpoints?

i am implementing an API using django-rest-framework and using drf-yasg to document and name my endpoints
every post method ends with create
i tried searching through the documentation and i cant find a way to do it
As someone mentioned in the comment, you should use the #swagger_auto_schema() decorator for your API in order to customize it. then set operation_id to change its name in swagger docs.
here is an exact example that'll solve your problem:
drf-yasg: How to change operationId?

djangorestframework browsable api: how to show all available endpoints urls?

In djangorestframework, there is a browsable api. But how do I show a user an entire bird's eye view of all the possible API calls that he/she can make? I can only see one at a time right now and the user would have to already know the correct URL beforehand
i.e.,
http://localhost:8000/users
http://localhost:8000/books
http://localhost:8000/book/1/author
Thank you!
The answer is as Klahnen said. Use this:
https://django-rest-swagger.readthedocs.io/en/latest/
It works out of the box for me and it is exactly what I was hoping for.
I still maintain, though, that the term browsable API implies that there is a table of contents available for consumers of your API to see. This app is a lifesaver and perhaps it should be included!
Django-Rest-Swagger as mentioned in the accepted answer is no longer maintained.
This is a good alternative
https://github.com/axnsan12/drf-yasg
Django-Rest-Swagger doesn't support OpenAPI 3.0 and is unlikely to support it soon, so if you want an actively maintained library that supports OpenAPI 3.0 then you should use drf-spectacular. It mostly works out of the box, and you can customize it a lot.
A side note:
Your api client needs access to the internet so that it gets the swagger UI or ReDoc from CDNs. Alternatively you can serve those static files from your service with an optional additional package, the drf-spectacular-sidecar

use django-rest-swagger 2 with custom swagger.json

I have a project build with django-rest-framework, and I want to use django-rest-swagger to get API documentation, so I made a swagger.json file via swagger editor, then my question is:
How can I make django-rest-swagger read and render my own swagger.json instead of auto-generated from code?
I've checked the django-rest-swagger doc over and over again but nothing found about that.
Any comment will be appreciated.
I know this is old post, but I ran into the same issue and wanted to provide my work around.
If you are trying to create a Swagger UI from an external JSON, this was my work around. I am using django but wanted to provide the swagger api of another framework and server. Here are two options:
The simplest solution is to just manually render the swagger html template and insert the endpoint url that provides the JSON inside SwaggerUi(), this is generally located in the last block.
Alternatively, if you cannot access the json directly or have a static file, create your own rest end point that either reads the file, or makes the request to the remote server, and then itself serves up the desired JSON. Reference this endpoint in your swagger template.

How does viewset aligns with rest methods

I am relatively new to DRF, but found viewsets an amazing abstraction technique for writing RESTful API. I am having a hard time correlating Viewsets with REST methods though. Let's say I have a viewset for Userprofiles and somebody new creates a profile on client.
Should this send a PUT or a POST ?
Which url should this request go to, http://user or http://user/new_id ?
If I want this profile only accessible to the user or admin(all CRUD operations), then where should I handle the code for making it inaccessible to others ?
Should I create a new permission ? If yes, should I handle rest methods in has_permission/has_object_permission ?
I have gone through the tutorial, and know how permissions/mixins works, but I am not able to connect these dots here.
1/ In general, POST is for creating new, PUT is for updating. See the docs on the SimpleRouter to show how the various types of Http methods align with various actions in your Django backend.
2/ You'll find that different situations call for different routing methods. If yours is standard, you may want to use a SimpleRouter like the example above. In that case, creating a new user would be a POST request to /user/ and updating a user would be a PUT request to /user/{{user_id}}/.
3/ To limit access to various API methods, you want to use Permissions. It's possible that you could use one of DRF's Custom Permissions. I've found that in general, if you want only the user to access his/her own profile, it's easier to either use conditional logic within a view (i.e., return a DRF PermissionDenied exception in the view logic if the request.user.pk is not the pk of that REST url. More often than not, I've used the UserPassesTestMixin from Django Braces, that works pretty well to filter user permissions.
4/ I guess the Django Braces mixin above answers this question. You should include a test_func method if you're using Django Braces that returns True if you want to grant the user access, and False otherwise.
Hope this helps! I agree that these are difficult parts of DRF and perhaps some of these could more effectively get incorporated into the source. Good luck!

User controlled presentation of data in widgets on a dashboard app - Best Practices?

Consider a very simple dashboard application in Django. It has 2 models:
Page
Widget
Naturally, Page and Widget have a ManyToMany relationship.
Like any good dashboard implementation, the designers can change 3 things in a widget:
Data source that drives the widget
Placement of widget on the Page
Presentation of Data inside a widget
The Data is specified using a URL field in the Widget and is being served by a REST API based on Django REST Framework with the django-filter backend.
The Placement on the Page is catered using the excellent Gridster.
This leaves the Presentation part. I have two possible solutions:
Attach a template TextField with the Widget. Data will be fetched from web services in JSON format and rendered according to the template (handlebars) defined in Widget on the client side.
Pass the template name as query string in the URL to the REST API and render the Data using the user-specified template.
Now that the context is clearly defined (hopefully), following are my questions:
Is there any way I can choose the first solution and still be able to use the automatic forms generated by the DRF Serializers?
If not, and I choose the second solution, are there any potential pit-falls regarding security, code maintenance, code quality, testing and the like? Why have I not seen anyone else doing this i.e. letting the user select the template via query string?
Is there any other solution that I am missing?
Your first options seems most promising: fetch the data as JSON and insert it into templates on the client. All good.
So can you do that "and still be able to use the automatic forms generated by the DRF Serializers"? — Short answer, it depends what you mean by "automatic forms".
Serializers take a data dictionary, validate it and (for ModelSerializer subclasses) convert it into a (model) object instance for you. If by "automatic forms" you mean will you still be able to this validation behaviour, then the answer is yes. Create your JSON payload on the client and send an appropriate HTTP request to the API. Django Rest Framework's Serializers will work as expected.
If (though) by "automatic forms" you mean will you still be able to use the HTML forms that DRF provides in its web broweasble API, then the answer is no. The browseable API is built around an HTML renderer returning entire web pages. These include a pretty-printed representation of the JSON you'll be using as well as the web-forms that, on this assumption, you're interested in.
If you go this route you'll need to generate the forms on the client, using whatever model, view, template and binding features your chosen library (libraries?) offer(s).
I hope that helps. Good luck.