{"id":391342,"date":"2024-06-29T09:46:12","date_gmt":"2024-06-29T09:46:12","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=391342"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-29T09:46:12","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=391342","title":{"rendered":"<span>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f API Django Rest Framework \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e DRF Spectacular<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0426\u0435\u043b\u044c\u044e \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 drf-spectacular \u0434\u043b\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f API \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0442\u0435\u0445\u043d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043a\u0440\u043e\u044e\u0442 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0433\u0438\u0431\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u041f\u043e\u0447\u0435\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e DRF Spectacular?<\/h2>\n<p><em>drf-spectacular<\/em> &#8212; \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0435\u0439\u0447\u0430\u0441 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f. <em>django-rest-swagger<\/em> \u0438 <em>drf-yasg<\/em> \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0438 \u0438 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u0443\u0436\u0435 \u043f\u0430\u0440\u0443-\u0442\u0440\u043e\u0439\u043a\u0443 \u043b\u0435\u0442.<\/p>\n<h2>\u041a\u0430\u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c DRF Spectacular \u0432 \u043f\u0440\u043e\u0435\u043a\u0442?<\/h2>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0430\u043c \u043f\u0430\u043a\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 <code>pip install drf-spectacular<\/code><\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 <code>INSTALLED_APPS<\/code> <\/p>\n<pre><code class=\"python\"> INSTALLED_APPS = [          # \u0412\u0421\u0415 \u0412\u0410\u0428\u0418 \u041f\u0420\u0418\u041b\u041e\u0416\u0415\u041d\u0418\u042f          'drf_spectacular',  ]<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <code>DEFAULT_SCHEMA_CLASS <\/code>\u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 <code>REST_FRAMEWORK <\/code>\u0432 <strong>settings.py. <\/strong>\u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u0430\u043c\u043e\u0439 \u0441\u0445\u0435\u043c\u044b. \u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u0441\u0432\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<pre><code class=\"python\">REST_FRAMEWORK = {          # \u0412\u0410\u0428\u0418 \u041d\u0410\u0421\u0422\u0420\u041e\u0419\u041a\u0418          'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',  }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c  \u0432 \u043d\u0430\u0448 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0444\u0430\u0439\u043b urls.py \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"python\">urlpatterns = [          # \u0412\u0410\u0428\u0418 URL-\u0410\u0414\u0420\u0415\u0421\u0410          path('api\/schema\/', SpectacularAPIView.as_view(), name='schema'),     path('api\/docs\/', SpectacularSwaggerView.as_view(url_name='schema'), name='docs'),   ]<\/code><\/pre>\n<p>\u041f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <strong>api\/schema\/<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f JSON-\u0441\u0445\u0435\u043c\u0430 \u043d\u0430\u0448\u0435\u0433\u043e API, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <strong>api\/docs\/<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0440\u043e\u0438\u0442\u044c\u0441\u044f Swagger-UI \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <a href=\"http:\/\/127.0.0.1:8000\/schema\/swagger\/\" rel=\"noopener noreferrer nofollow\"> <u>http:\/\/127.0.0.1:8000\/api\/docs\/<\/u><\/a> \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u043d\u0430\u0448\u0438\u0445 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0432\u043e\u0442 \u0432 \u0442\u0430\u043a\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ceb\/53e\/19c\/ceb53e19c63989a54527751b5826d88e.png\" alt=\"\u041e\u0431\u0449\u0438\u0439 \u0432\u0438\u0434 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 Swagger-UI \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \" title=\"\u041e\u0431\u0449\u0438\u0439 \u0432\u0438\u0434 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 Swagger-UI \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \" width=\"1395\" height=\"621\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ceb\/53e\/19c\/ceb53e19c63989a54527751b5826d88e.png\"\/><\/p>\n<div><figcaption>\u041e\u0431\u0449\u0438\u0439 \u0432\u0438\u0434 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 Swagger-UI \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. <\/figcaption><\/div>\n<\/figure>\n<h2>\u0411\u0430\u0437\u043e\u0432\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0431\u043e\u043b\u0435\u0435 \u0433\u0438\u0431\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435. \u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 <strong>\/groups\/<\/strong><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d77\/68d\/c44\/d7768dc44ee05e67b6b2d39391f041c4.png\" alt=\"\" title=\"\" width=\"1393\" height=\"828\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d77\/68d\/c44\/d7768dc44ee05e67b6b2d39391f041c4.png\"\/><\/figure>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u0417\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0447\u0435\u0442\u044b\u0440\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u0430:<\/p>\n<ul>\n<li>\n<p>\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430 \u0438 \u0434\u0430\u043d\u044b \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c\u044b\u0435 query-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438\u043c\u0435\u0440 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0443\u0441-\u043a\u043e\u0434\u0430 (200, 201, 400, 404 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435)<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430.<\/p>\n<ol>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 <code>@extend_schema_view<\/code> \u0438 \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>@extend_schema<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e<\/p>\n<\/li>\n<li>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432 doc-string \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"python\"># \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 @extend_schema_view(     list=extend_schema(             summary=\"\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0441\u0442\u043e\u0432\",         ),     update=extend_schema(         summary=\"\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430\",     ),     partial_update=extend_schema(         description=\"\"\"Lorem ipsum dolor sit amet, consectetur adipiscing elit.          Cras euismod vehicula hendrerit. Integer placerat lobortis purus, molestie          finibus nibh gravida sed. Etiam pretium gravida velit, et rutrum nisi posuere at.          Proin hendrerit eros et enim placerat, in commodo lorem tristique. Donec hendrerit ultrices          nulla, a maximus diam consectetur id. Cras suscipit ligula vitae sem vulputate vulputate.          Duis enim turpis, mollis at maximus nec, tempus ac erat. Nullam at eleifend est, non lacinia erat.          Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae;          Nulla congue condimentum arcu, id sodales dolor aliquet nec. Nullam a consequat neque.\"\"\",     ),     create=extend_schema(             summary=\"\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430\",         ), ) class PostViewSet(viewsets.ModelViewSet):     queryset = Post.objects.all()     serializer_class = PostSerializer     # \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a \u0436\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438  \u00a0\u00a0\u00a0\u00a0@extend_schema(summary=\"Test description of retrieve method\") \u00a0\u00a0\u00a0\u00a0def retrieve(self, request, *args, **kwargs):  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# some logic  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Response(status=status.HTTP_200_OK)  \u00a0\u00a0\u00a0\u00a0def destroy(self, request, *args, **kwargs):         # \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0447\u0435\u0440\u0435\u0437 doc-string  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"\"\"Test description of destroy method\"\"\"  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Response(status=status.HTTP_200_OK)<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>summary<\/code>, \u0435\u0441\u043b\u0438 \u0434\u043b\u0438\u043d\u043d\u043e\u0435 &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c description. \u041b\u0438\u0431\u043e \u043e\u0431\u0430, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u0438 \u0434\u043b\u0438\u043d\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435. \u0423 <code>summary<\/code> \u0435\u0441\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u043b\u044e\u0441 &#8212; \u043e\u043d \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430 \u0438 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0c3\/b53\/cba\/0c3b53cbaf4cacc765f15bdb722c003c.png\" alt=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u0432 Swagger UI\" title=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u0432 Swagger UI\" width=\"1508\" height=\"520\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0c3\/b53\/cba\/0c3b53cbaf4cacc765f15bdb722c003c.png\"\/><\/p>\n<div><figcaption>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u0432 Swagger UI<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0435\u0433, \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432. \u0415\u0441\u043b\u0438 \u0443 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0442\u0435\u0433, \u044d\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e \u0438 \u043f\u043e\u0438\u0441\u043a \u043d\u0443\u0436\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438. <\/p>\n<p>\u0422\u0435\u0433\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>@extend_schema <\/code>\u043d\u0430\u0434 <code>@extend_schema_view<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u0441\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0434\u043d\u0438\u043c \u0442\u0435\u0433\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u044b  \u0432 \u043e\u0434\u0438\u043d \u0431\u043b\u043e\u043a.<\/p>\n<pre><code class=\"python\">@extend_schema(tags=[\"Posts\"]) @extend_schema_view(     retrieve=extend_schema(         summary=\"\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u0441\u0442\u0435\",         ....<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432. \u0412 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 responses \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0432\u0438\u0434\u0430 {&#171;\u043a\u043e\u0434 \u043e\u0442\u0432\u0435\u0442\u0430&#187;: &#171;\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0438\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 OpenApiResponse&#187;}<\/p>\n<pre><code class=\"python\">class DummyDetailSerializer(serializers.Serializer):     status = serializers.IntegerField()   class DummyDetailAndStatusSerializer(serializers.Serializer):     status = serializers.IntegerField()     details = serializers.CharField()  @extend_schema(tags=[\"Posts\"]) @extend_schema_view(     retrieve=extend_schema(         summary=\"\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u0441\u0442\u0435\",         responses={             status.HTTP_200_OK: PostSerializer,             status.HTTP_400_BAD_REQUEST: DummyDetailSerializer,             status.HTTP_401_UNAUTHORIZED: DummyDetailSerializer,             status.HTTP_403_FORBIDDEN: DummyDetailAndStatusSerializer,             status.HTTP_500_INTERNAL_SERVER_ERROR: OpenApiResponse(                 response=None,                 description='\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 500 \u043e\u0442\u0432\u0435\u0442\u0430'),         },     ),<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 <code>DummyDetailSerializer\/DummyDetailAndStatusSerializer<\/code>.<\/p>\n<p>\u0422\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0430\u0448\u0438 \u043e\u0442\u0432\u0435\u0442\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fa1\/a1d\/560\/fa1a1d560928925d3e108051d9bd8919.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 Swagger UI\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 Swagger UI\" width=\"1408\" height=\"998\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fa1\/a1d\/560\/fa1a1d560928925d3e108051d9bd8919.png\"\/><\/p>\n<div><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 Swagger UI<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <strong>update<\/strong>. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 <code>parameters<\/code> \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043b\u0438\u0431\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435.<\/p>\n<pre><code class=\"python\">update=extend_schema(         summary=\"\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430\",         request=PostSerializer,         responses={             status.HTTP_200_OK: PostSerializer,             status.HTTP_400_BAD_REQUEST: DummyDetailSerializer,             status.HTTP_401_UNAUTHORIZED: DummyDetailSerializer,             status.HTTP_403_FORBIDDEN: DummyDetailAndStatusSerializer,         },         parameters=[             OpenApiParameter(                 name='some_new_parameter',                 location=OpenApiParameter.QUERY,                 description='some new parameter for update post',                 required=False,                 type=int             ),         ]     ),<\/code><\/pre>\n<p>\u0422\u0430\u043a \u044d\u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/faa\/c92\/335\/faac9233512eaad033a5fea0b797393c.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432\" width=\"1455\" height=\"842\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/faa\/c92\/335\/faac9233512eaad033a5fea0b797393c.png\"\/><\/p>\n<div><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 &#8212; <strong>location<\/strong>. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <em>OpenApiParameter.QUERY<\/em>. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a query \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 ?some_new_parameter=123. <\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b:<\/p>\n<ul>\n<li>\n<p> OpenApiParameter.PATH &#8212; \u0434\u043e\u043f. \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432 url<\/p>\n<\/li>\n<li>\n<p>OpenApiParameter.HEADER &#8212; \u0434\u043e\u043f. \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432 headers<\/p>\n<\/li>\n<li>\n<p>OpenApiParameter.COOKIE &#8212; \u0434\u043e\u043f. \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432 cookies<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u0412 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 examples \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 OpenApiExample. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"python\">create=extend_schema(             summary=\"\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430\",             request=PostSerializer,             responses={                 status.HTTP_200_OK: PostSerializer,                 status.HTTP_400_BAD_REQUEST: DummyDetailSerializer,                 status.HTTP_401_UNAUTHORIZED: DummyDetailSerializer,                 status.HTTP_403_FORBIDDEN: DummyDetailAndStatusSerializer,             },             examples=[                 OpenApiExample(                     \"Post example\",                     description=\"Test example for the post\",                     value=                     {                         \"title\": \"testuser\",                         \"text\": \"Some text for post\",                         \"category\": 1,                         \"author\": 1,                     },                     status_codes=[str(status.HTTP_200_OK)],                 ),             ],         ),<\/code><\/pre>\n<p>\u041d\u0430\u0448 \u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9e1\/2cc\/285\/9e12cc285544c9e531924ef6ac0a59e2.png\" alt=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432 Swagger UI.\" title=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432 Swagger UI.\" width=\"1452\" height=\"539\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9e1\/2cc\/285\/9e12cc285544c9e531924ef6ac0a59e2.png\"\/><\/p>\n<div><figcaption>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432 Swagger UI.<\/figcaption><\/div>\n<\/figure>\n<h2>\u041e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 settings.py \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"python\">SPECTACULAR_SETTINGS = {     \"TITLE\": \"Post API\", # \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430     \"VERSION\": \"0.0.1\", # \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430     \"SERVE_INCLUDE_SCHEMA\": False, # \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 \/schema     \"SWAGGER_UI_SETTINGS\": {         \"filter\": True, # \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u043f\u043e \u0442\u0435\u0433\u0430\u043c     },     \"COMPONENT_SPLIT_REQUEST\": True }<\/code><\/pre>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0433\u0443 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e drf-spectacular &#8212; \u044d\u0442\u043e \u0433\u0438\u0431\u043a\u0438\u0439 \u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0425\u043e\u0440\u043e\u0448\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f API \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043d\u0430 \u0432\u0441\u0435\u0445 \u044d\u0442\u0430\u043f\u0430\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043e\u0434\u0430.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/733942\/\"> https:\/\/habr.com\/ru\/articles\/733942\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0426\u0435\u043b\u044c\u044e \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 drf-spectacular \u0434\u043b\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f API \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0442\u0435\u0445\u043d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043a\u0440\u043e\u044e\u0442 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0433\u0438\u0431\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u041f\u043e\u0447\u0435\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e DRF Spectacular?<\/h2>\n<p><em>drf-spectacular<\/em> &#8212; \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0435\u0439\u0447\u0430\u0441 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f. <em>django-rest-swagger<\/em> \u0438 <em>drf-yasg<\/em> \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0438 \u0438 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u0443\u0436\u0435 \u043f\u0430\u0440\u0443-\u0442\u0440\u043e\u0439\u043a\u0443 \u043b\u0435\u0442.<\/p>\n<h2>\u041a\u0430\u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c DRF Spectacular \u0432 \u043f\u0440\u043e\u0435\u043a\u0442?<\/h2>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0430\u043c \u043f\u0430\u043a\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 <code>pip install drf-spectacular<\/code><\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 <code>INSTALLED_APPS<\/code> <\/p>\n<pre><code class=\"python\"> INSTALLED_APPS = [          # \u0412\u0421\u0415 \u0412\u0410\u0428\u0418 \u041f\u0420\u0418\u041b\u041e\u0416\u0415\u041d\u0418\u042f          'drf_spectacular',  ]<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <code>DEFAULT_SCHEMA_CLASS <\/code>\u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 <code>REST_FRAMEWORK <\/code>\u0432 <strong>settings.py. <\/strong>\u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u0430\u043c\u043e\u0439 \u0441\u0445\u0435\u043c\u044b. \u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u0441\u0432\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<pre><code class=\"python\">REST_FRAMEWORK = {          # \u0412\u0410\u0428\u0418 \u041d\u0410\u0421\u0422\u0420\u041e\u0419\u041a\u0418          'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',  }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c  \u0432 \u043d\u0430\u0448 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0444\u0430\u0439\u043b urls.py \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"python\">urlpatterns = [          # \u0412\u0410\u0428\u0418 URL-\u0410\u0414\u0420\u0415\u0421\u0410          path('api\/schema\/', SpectacularAPIView.as_view(), name='schema'),     path('api\/docs\/', SpectacularSwaggerView.as_view(url_name='schema'), name='docs'),   ]<\/code><\/pre>\n<p>\u041f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <strong>api\/schema\/<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f JSON-\u0441\u0445\u0435\u043c\u0430 \u043d\u0430\u0448\u0435\u0433\u043e API, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <strong>api\/docs\/<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0440\u043e\u0438\u0442\u044c\u0441\u044f Swagger-UI \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <a href=\"http:\/\/127.0.0.1:8000\/schema\/swagger\/\" rel=\"noopener noreferrer nofollow\"> <u>http:\/\/127.0.0.1:8000\/api\/docs\/<\/u><\/a> \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u043d\u0430\u0448\u0438\u0445 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0432\u043e\u0442 \u0432 \u0442\u0430\u043a\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041e\u0431\u0449\u0438\u0439 \u0432\u0438\u0434 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 Swagger-UI \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. <\/figcaption><\/div>\n<\/figure>\n<h2>\u0411\u0430\u0437\u043e\u0432\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0431\u043e\u043b\u0435\u0435 \u0433\u0438\u0431\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435. \u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 <strong>\/groups\/<\/strong><\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u0417\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0447\u0435\u0442\u044b\u0440\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u0430:<\/p>\n<ul>\n<li>\n<p>\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430 \u0438 \u0434\u0430\u043d\u044b \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c\u044b\u0435 query-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438\u043c\u0435\u0440 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0443\u0441-\u043a\u043e\u0434\u0430 (200, 201, 400, 404 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435)<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430.<\/p>\n<ol>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 <code>@extend_schema_view<\/code> \u0438 \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>@extend_schema<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e<\/p>\n<\/li>\n<li>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432 doc-string \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"python\"># \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 @extend_schema_view(     list=extend_schema(             summary=\"\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0441\u0442\u043e\u0432\",         ),     update=extend_schema(         summary=\"\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430\",     ),     partial_update=extend_schema(         description=\"\"\"Lorem ipsum dolor sit amet, consectetur adipiscing elit.          Cras euismod vehicula hendrerit. Integer placerat lobortis purus, molestie          finibus nibh gravida sed. Etiam pretium gravida velit, et rutrum nisi posuere at.          Proin hendrerit eros et enim placerat, in commodo lorem tristique. Donec hendrerit ultrices          nulla, a maximus diam consectetur id. Cras suscipit ligula vitae sem vulputate vulputate.          Duis enim turpis, mollis at maximus nec, tempus ac erat. Nullam at eleifend est, non lacinia erat.          Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae;          Nulla congue condimentum arcu, id sodales dolor aliquet nec. Nullam a consequat neque.\"\"\",     ),     create=extend_schema(             summary=\"\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430\",         ), ) class PostViewSet(viewsets.ModelViewSet):     queryset = Post.objects.all()     serializer_class = PostSerializer     # \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a \u0436\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438  \u00a0\u00a0\u00a0\u00a0@extend_schema(summary=\"Test description of retrieve method\") \u00a0\u00a0\u00a0\u00a0def retrieve(self, request, *args, **kwargs):  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# some logic  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Response(status=status.HTTP_200_OK)  \u00a0\u00a0\u00a0\u00a0def destroy(self, request, *args, **kwargs):         # \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0447\u0435\u0440\u0435\u0437 doc-string  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"\"\"Test description of destroy method\"\"\"  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Response(status=status.HTTP_200_OK)<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>summary<\/code>, \u0435\u0441\u043b\u0438 \u0434\u043b\u0438\u043d\u043d\u043e\u0435 &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c description. \u041b\u0438\u0431\u043e \u043e\u0431\u0430, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u0438 \u0434\u043b\u0438\u043d\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435. \u0423 <code>summary<\/code> \u0435\u0441\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u043b\u044e\u0441 &#8212; \u043e\u043d \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430 \u0438 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u0432 Swagger UI<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0435\u0433, \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432. \u0415\u0441\u043b\u0438 \u0443 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0442\u0435\u0433, \u044d\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e \u0438 \u043f\u043e\u0438\u0441\u043a \u043d\u0443\u0436\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438. <\/p>\n<p>\u0422\u0435\u0433\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>@extend_schema <\/code>\u043d\u0430\u0434 <code>@extend_schema_view<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u0441\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0434\u043d\u0438\u043c \u0442\u0435\u0433\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u044b  \u0432 \u043e\u0434\u0438\u043d \u0431\u043b\u043e\u043a.<\/p>\n<pre><code class=\"python\">@extend_schema(tags=[\"Posts\"]) @extend_schema_view(     retrieve=extend_schema(         summary=\"\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u0441\u0442\u0435\",         ....<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432. \u0412 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 responses \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0432\u0438\u0434\u0430 {&#171;\u043a\u043e\u0434 \u043e\u0442\u0432\u0435\u0442\u0430&#187;: &#171;\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0438\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 OpenApiResponse&#187;}<\/p>\n<pre><code class=\"python\">class DummyDetailSerializer(serializers.Serializer):     status = serializers.IntegerField()   class DummyDetailAndStatusSerializer(serializers.Serializer):     status = serializers.IntegerField()     details = serializers.CharField()  @extend_schema(tags=[\"Posts\"]) @extend_schema_view(     retrieve=extend_schema(         summary=\"\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u0441\u0442\u0435\",         responses={             status.HTTP_200_OK: PostSerializer,             status.HTTP_400_BAD_REQUEST: DummyDetailSerializer,             status.HTTP_401_UNAUTHORIZED: DummyDetailSerializer,             status.HTTP_403_FORBIDDEN: DummyDetailAndStatusSerializer,             status.HTTP_500_INTERNAL_SERVER_ERROR: OpenApiResponse(                 response=None,                 description='\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 500 \u043e\u0442\u0432\u0435\u0442\u0430'),         },     ),<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 <code>DummyDetailSerializer\/DummyDetailAndStatusSerializer<\/code>.<\/p>\n<p>\u0422\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0430\u0448\u0438 \u043e\u0442\u0432\u0435\u0442\u044b:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 Swagger UI<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <strong>update<\/strong>. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 <code>parameters<\/code> \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043b\u0438\u0431\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435.<\/p>\n<pre><code class=\"python\">update=extend_schema(         summary=\"\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430\",         request=PostSerializer,         responses={             status.HTTP_200_OK: PostSerializer,             status.HTTP_400_BAD_REQUEST: DummyDetailSerializer,             status.HTTP_401_UNAUTHORIZED: DummyDetailSerializer,             status.HTTP_403_FORBIDDEN: DummyDetailAndStatusSerializer,         },         parameters=[             OpenApiParameter(                 name='some_new_parameter',                 location=OpenApiParameter.QUERY,                 description='some new parameter for update post',                 required=False,                 type=int             ),         ]     ),<\/code><\/pre>\n<p>\u0422\u0430\u043a \u044d\u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 &#8212; <strong>location<\/strong>. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <em>OpenApiParameter.QUERY<\/em>. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a query \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 ?some_new_parameter=123. <\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b:<\/p>\n<ul>\n<li>\n<p> OpenApiParameter.PATH &#8212; \u0434\u043e\u043f. \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432 url<\/p>\n<\/li>\n<li>\n<p>OpenApiParameter.HEADER &#8212; \u0434\u043e\u043f. \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432 headers<\/p>\n<\/li>\n<li>\n<p>OpenApiParameter.COOKIE &#8212; \u0434\u043e\u043f. \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432 cookies<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u0412 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 examples \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 OpenApiExample. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"python\">create=extend_schema(             summary=\"\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430\",             request=PostSerializer,             responses={                 status.HTTP_200_OK: PostSerializer,                 status.HTTP_400_BAD_REQUEST: DummyDetailSerializer,                 status.HTTP_401_UNAUTHORIZED: DummyDetailSerializer,                 status.HTTP_403_FORBIDDEN: DummyDetailAndStatusSerializer,             },             examples=[                 OpenApiExample(                     \"Post example\",                     description=\"Test example for the post\",                     value=                     {                         \"title\": \"testuser\",                         \"text\": \"Some text for post\",                         \"category\": 1,                         \"author\": 1,                     },                     status_codes=[str(status.HTTP_200_OK)],                 ),             ],         ),<\/code><\/pre>\n<p>\u041d\u0430\u0448 \u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432 Swagger UI.<\/figcaption><\/div>\n<\/figure>\n<h2>\u041e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 settings.py \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"python\">SPECTACULAR_SETTINGS = {     \"TITLE\": \"Post API\", # \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430     \"VERSION\": \"0.0.1\", # \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430     \"SERVE_INCLUDE_SCHEMA\": False, # \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 \/schema     \"SWAGGER_UI_SETTINGS\": {         \"filter\": True, # \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u043f\u043e \u0442\u0435\u0433\u0430\u043c     },     \"COMPONENT_SPLIT_REQUEST\": True }<\/code><\/pre>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0433\u0443 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e drf-spectacular &#8212; \u044d\u0442\u043e \u0433\u0438\u0431\u043a\u0438\u0439 \u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0425\u043e\u0440\u043e\u0448\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f API \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043d\u0430 \u0432\u0441\u0435\u0445 \u044d\u0442\u0430\u043f\u0430\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043e\u0434\u0430.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/733942\/\"> https:\/\/habr.com\/ru\/articles\/733942\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-391342","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/391342","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=391342"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/391342\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=391342"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=391342"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=391342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}