Version with swagger OpenAPI 3.0
https://gitlab.com/halia-ca/arnaud-dev/-/tree/django-postgres-blog-swagger-drf-spectacular
Django blog project with postgres and REST API.
https://gitlab.com/halia-ca/arnaud-dev/-/tree/django-postgres-blog-v2
This guide has been written with the folowing versions:
Django == 4.0.2
psycopg2 == 2.9.3
coverage == 6.3.1
djangorestframework == 3.13.1
django-filter == 21.1
dj-rest-auth == 2.2.3
drf-spectacular == 0.21.2
drf-spectacular can be found here:
https://github.com/tfranzel/drf-spectacular
pip install drf-spectacular
Do not forget to include in requirements.txt
Add metadata about your applications
SPECTACULAR_SETTINGS = {
'TITLE': 'Your Project API',
'DESCRIPTION': 'Your project description',
'VERSION': '1.0.0',
# OTHER SETTINGS
}
drf-spectacular
to INSTALLED_APPS in settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', # Manually added REST API
'django_filters', # Manually added REST API
'rest_framework.authtoken', # Manually added REST API
'dj_rest_auth', # Manually added REST API
'drf_spectacular', # Manually added for swagger OpenAPI 3.0
'posts', # Manually added
]
drf-spectacular
AutoSchema with DRF.REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend',
'rest_framework.filters.SearchFilter',
],
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
user_management/serializer.py
from django.contrib.auth.models import User, Group
from rest_framework import serializers
class UserSerializer(serializers.HyperlinkedModelSerializer):
"""UserSerializer/"""
class Meta:
"""Meta."""
model = User
fields = ['url', 'username', 'email', 'groups']
class GroupSerializer(serializers.HyperlinkedModelSerializer):
"""GroupSerializer."""
class Meta:
"""Meta."""
model = Group
fields = ['url', 'name']
user_management/views.py
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from user_management.serializers import UserSerializer, GroupSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
permission_classes = [IsAuthenticated]
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
permission_classes = [IsAuthenticated]
user_management/urls.py
from rest_framework import routers
from user_management.views import UserViewSet, GroupViewSet
router = routers.DefaultRouter()
router.register(r"users", UserViewSet)
router.register(r"groups", GroupViewSet)
from rest_framework import serializers
from posts.models import BlogPost
class Serializer(serializers.HyperlinkedModelSerializer):
"""Serializer."""
class Meta:
"""Meta."""
model = BlogPost
fields = ['url', 'id', 'title', 'author', 'last_updated', 'created_on',
'published', 'content']
blog/urls.py
from django.contrib import admin
from django.urls import path, include
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from rest_framework import routers
from posts.urls import router as posts_router
from user_management.urls import router as user_management_router
router = routers.DefaultRouter()
router.registry.extend(posts_router.registry)
router.registry.extend(user_management_router.registry)
urlpatterns = [
path("schema/", SpectacularAPIView.as_view(), name="schema"),
path(
"swagger/",
SpectacularSwaggerView.as_view(
template_name="swagger-ui.html", url_name="schema"
),
name="swagger-ui",
),
path('api/', include(router.urls), name='api'),
path('admin/', admin.site.urls),
path('auth/', include('dj_rest_auth.urls')),
path('', include('posts.urls')),
]
templates/swagger-ui.html
<!DOCTYPE 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="https://unpkg.com/swagger-ui-dist@3/swagger-ui.css">
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
<script>
const ui = SwaggerUIBundle({
url: "{% url 'schema' %}",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "BaseLayout",
requestInterceptor: (request) => {
request.headers['X-CSRFToken'] = "{{ csrf_token }}"
return request;
}
})
</script>
</body>
</html>