10

I am trying to document my Django REST API with built-in methods. Here is the urls.py:

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.conf.urls import url
from django.views.generic.base import TemplateView
from rest_framework.documentation import include_docs_urls

urlpatterns = [
    path('api/', include('api.urls')),
    path('admin/', admin.site.urls),
    path('', include('main.urls')),
    path('swagger-ui/', TemplateView.as_view(
        template_name='swagger-ui.html',
        extra_context={'schema_url': 'openapi-schema'}
    ), name='swagger-ui'),
    url(r'^.*', TemplateView.as_view(template_name="home.html")),

] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

static/templates/swagger-ui.html:

<html>
  <head>
    <title>Swagger</title>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="//unpkg.com/swagger-ui-dist@3/swagger-ui.css" />
  </head>
  <body>
    <div id="swagger-ui"></div>
    <script src="//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
    <script>
    
    const ui = SwaggerUIBundle({
        url: "{% url schema_url %}",
        dom_id: '#swagger-ui',
        presets: [
          SwaggerUIBundle.presets.apis,
          SwaggerUIBundle.SwaggerUIStandalonePreset
        ],
        layout: "BaseLayout"
      })
    </script>
  </body>
</html>

However, I don't understand where should we allocate the openapi-schema file? Is it a .yml file or .js? And is there a way to generate it automatically?

Aigerim Sadir
  • 353
  • 5
  • 18

1 Answers1

20

The schema_url should point to a valid OpenAPI spec. Swagger UI can handle both JSON and YAML files.

The easiest way to point Swagger UI to a valid schema is by using a dynamic schema view, which I think you've skimmed over.

From the docs:

from rest_framework.schemas import get_schema_view

    urlpatterns = [
        # ...
        # Use the `get_schema_view()` helper to add a `SchemaView` to project URLs.
        #   * `title` and `description` parameters are passed to `SchemaGenerator`.
        #   * Provide view name for use with `reverse()`.
        path('openapi', get_schema_view(
            title="Your Project",
            description="API for all things …",
            version="1.0.0"
        ), name='openapi-schema'),
        # ...
    ] 

If you add this URLpattern url: "{% url schema_url %}", in your template, it will be able to find the dynamically generated schema.

Nico Griffioen
  • 5,143
  • 2
  • 27
  • 36
  • Thank you for your answer! But what can I do to customize the schema? I generated a static schema with manage.py generateschema > openapi-schema.yml but still dont know how to use it – Aigerim Sadir Jun 09 '20 at 11:50
  • What do you mean by customize the schema? You OpenAPI spec should be a reflection of you API, so there isn't really much to customize, besides changing your API. – Nico Griffioen Jun 09 '20 at 12:34
  • 1
    I mean how could I change the HTML? Thanks for your aswers! – Aigerim Sadir Jun 10 '20 at 03:25
  • 2
    Well, if you generated a static schema, you'll need to add it to your staticfiles folder (This depends on you own configuration, for more information on static files, check https://docs.djangoproject.com/en/3.0/howto/static-files/). You can then include the url of the schema in your template by replacing `"{% url schema_url %}",` with `"{% static "/openapi-schema.yml" %}"` – Nico Griffioen Jun 10 '20 at 09:40
  • So what should it be for the dynamically generated schema? The path is `openapi` so `schema_url` should be `openapi`, I also tried `openapi?format=openapi-json` but it still can't find it. I can access the schema json with the browser. – Velkan Nov 23 '22 at 14:33
  • Ok, if you have set app_name in the app's `urls.py` (e.g. `app_name = 'my_app'`) or if you included the app with a namespace (e.g. `include('myapp.urls', namespace='myapp'`), then you need to mention it: `extra_context={"schema_url": f"{app_name}:openapi-schema"}`. (https://stackoverflow.com/a/38390178/4742108) – Velkan Nov 23 '22 at 14:47