آفلاین سازی swagger در django و ماژول drf-spectacular
به صورت پیشفرض برای drf-yasg تمام asset ها بصورت آفلاین بارگزاری می شوند ولی برای drf-spectacular هنوز هم به cdn های خارجی برای این کار احتیاج است.
ستاپ اولیه پروژه
خوشبختانه طبق قواعد جنگو می توان یک ساختار نسبتا راحت را برای جاگیزینی این asset های آنلاین با محلی و یا با آروان انجام داد. از تنظیمات مربوط به templates و static های جنگو مطمئن بشید که به شکل زیر باشن.
# settings.py
# templates config
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / 'templates'],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
# statics
STATIC_URL = "/static/"
MEDIA_URL = "/media/"
STATIC_ROOT = BASE_DIR / "staticfiles"
MEDIA_ROOT = BASE_DIR / "media"
STATICFILES_DIRS = [
BASE_DIR / "static",
]
ستاپ مربوط به drf-spectacular
اول از نصب و ستاپ اولیه drf-spectacular مطمئن بشید.
# settings.py
# installled apps
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
...
"rest_framework",
"drf_spectacular",
...
]
# spectacular settings (minimal)
SPECTACULAR_SETTINGS = {
...
"TITLE": "Your Project API",
...
}
# drf configs
REST_FRAMEWORK = {
...
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
...
}
تنظیمات urls
...
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
urlpatterns = [
...
path('schema/', SpectacularAPIView.as_view(), name='schema'),
path('swagger/', SpectacularSwaggerView.as_view(url_name='schema'),
name='swagger-ui'),
...
]
وارد صفحه مربوط به Swagger شده و ببینید که چه css و یا js هایی لود نمی شوند.
https://cdn.jsdelivr.net/npm/swagger-ui-dist@latest/swagger-ui.css
https://cdn.jsdelivr.net/npm/swagger-ui-dist@latest/swagger-ui-bundle.js
https://cdn.jsdelivr.net/npm/swagger-ui-dist@latest/swagger-ui-standalone-preset.js
اما راه حل این موضوع سادس، طبق قواعد جنگو وقتی شما یک template را هم نام و هم دایرکتوری مربوط به ماژول در نظر میگیرید محتوایت آن باز نویسی شده و جایگزین می شود.
دانلود و قرار دادن css و js ها در پوشه static
- یک پوشه با نام drf_spectacular در دایرکتوری static بسازید
- هر 3 فایلی که لود نمی شد رو از آدرس swagger-ui | ArvanCloud دانلود کنید. (می تونین نسخه های min اون رو دانلود کنین)
- بعد از دانلود دایرکتوری مورد نظر و اسامی رو در نظر بگیرید تا در مرحله بعد استفاده کنیم.
در نهایت برای این بخش به این شکل خواهد بود:

ایجاد template لازم برای جایگزینی
برای اینکه به جای صفحه اصلی که asset های آنلاین را درخواست می کند یک صفحه دیگر جایگزین کنیم کافیست که در پوشه templates در پروژه و به خصوص داخل دایرکتوری drf_spectacular فایلی با اسم مشخص به نام swagger_ui.html ایجاد و محتویات زیر را جایگزین کنیم.
{% load static %}
<!DOCTYPE html>
<html>
<head>
{% block head %}
<title>{{ title|default:"Swagger" }}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% if favicon_href %}
<link rel="icon" href="{{ favicon_href }}">{% endif %}
<link rel="stylesheet" href="{% static 'drf_spectacular/swagger-ui.min.css' %}">
<style>
html {
box-sizing: border-box;
overflow-y: scroll;
}
*,
*:after,
*:before {
box-sizing: inherit;
}
body {
background: #fafafa;
margin: 0;
}
</style>
{% endblock head %}
</head>
<body>
{% block body %}
<div id="swagger-ui"></div>
<script src="{% static 'drf_spectacular/swagger-ui-bundle.min.js' %}"></script>
<script src="{% static 'drf_spectacular/swagger-ui-standalone-preset.min.js' %}"></script>
{% if script_url %}
<script src="{{ script_url }}"></script>
{% else %}
<script>
{% include template_name_js %}
</script>
{% endif %}
{% endblock %}
</body>
</html>
باید به این شکل باشد:

قطعه کد بالا در اصل جایگزین ساختار اصلی خواهد شد و دیگر نیاز به تغییر چیزی نخواهد بود و حالا می تونین به صفحه swagger دسترسی پیدا کنین.
ثبت دیدگاه
دیدگاه کاربران (9)
Amir
12 , فروردین , 1405 - 17:18 بعد از ظهرسلام
خیلی ممنون استاد بیگدلی
حسین
24 , فروردین , 1405 - 08:51 قبل از ظهرسلام استاد
متاسفانه django debug toolbar هم همین مشکل رو داره. احیانا asset های دیباگ تولبار رو ندارید اپلود کنید؟
علی بیگدلی
24 , فروردین , 1405 - 10:10 قبل از ظهراین asset ها از داخل خود اپلیکیشن میاد cdn نیستن احتمالا باید یه بار collect static کنین