使用Django + REST框架 + Swagger + JWT + docker-compose来搭建开发环境
目的 – 为了什么而努力或追求的目标或理由。
在Mac上的Docker上搭建开发服务器,并使其能够通过下面的URL在浏览器中访问。如果能够访问下面的URL,则搭建成功。
环境
macOSX:蒙特利
Python:3.10.4
Django:3.2.13
Django REST框架:3.13.1
Django REST框架JWT:1.11.0
drf-spectacular(swagger):0.22.1
以下是我環境構築的履歷。
Django 环境构建历史
创建本地代码仓库
$ mkdir Django3.2-DRF
$ cd Django3.2-DRF/
$ echo '# Django3.2-DRF' > README.md
$ (echo '*.pyc'
echo '__pycache__'
echo 'db.sqlite3'
echo 'venv/*'
) > .gitignore
$ git init
$ git add .
$ git commit -m 'first commit'
↓这个操作后的目录结构
Django3.2-DRF
├── .git
├── .gitignore
└── README.md
创建虚拟环境
$ python3 -m venv venv
$ source ./venv/bin/activate
$ pip install --upgrade pip
↓完成此操作后的目录结构
Django3.2-DRF
├── .git
├── .gitignore
├── README.md
└── venv # virtualenv用に新規作成
安裝Django
请从https://www.djangoproject.com/download/ 网站上查询最新的LTS版本并进行安装。
$ pip install Django==3.2.13
$ python -m django --version
3.2.13
创建项目
$ django-admin startproject config .
$ git add config/ manage.py
$ git commit -m 'project 作成'
↓ 完成此任务后的目录结构
Django3.2-DRF
├── .git
├── .gitignore
├── README.md
├── config # プロジェクトが作成された
│ ├── __init__.py # プロジェクトが作成された
│ ├── settings.py # プロジェクトが作成された
│ ├── urls.py # プロジェクトが作成された
│ └── wsgi.py # プロジェクトが作成された
├── manage.py # プロジェクトが作成された
└── venv
创建一个名为sample_app的应用程序。
$ python manage.py startapp sample_app
$ git add sample_app
$ git commit -m 'sample_app 作成'
↓ 完成此任务后的目录结构
Django3.2-DRF
├── .git
├── .gitignore
├── README.md
├── config
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── sample_app # アプリケーションが作成された
│ ├── __init__.py # アプリケーションが作成された
│ ├── admin.py # アプリケーションが作成された
│ ├── apps.py # アプリケーションが作成された
│ ├── migrations # アプリケーションが作成された
│ ├── models.py # アプリケーションが作成された
│ ├── tests.py # アプリケーションが作成された
│ └── views.py # アプリケーションが作成された
└── venv
示例应用程序的应用程序注册
编辑文件
Django3.2-DRF
└── config
└── settings.py ← これ
$ vi config/settings.py
与现有文件的不同之处
$ git diff config/settings.py
diff --git a/config/settings.py b/config/settings.py
index 14a482e..0b0f505 100644
--- a/config/settings.py
+++ b/config/settings.py
@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
+ 'sample_app',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
$ git add config/settings.py
$ git commit -m 'sample_app のアプリケーション登録'
创建视图
编辑文件
Django3.2-DRF
└── sample_app
└── views.py ← これ
$ vi sample_app/views.py
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world.")
$ git add sample_app/views.py
$ git commit -m 'テストビューの作成'
创建新的应用程序URLConf
编辑文件
Django3.2-DRF
└── sample_app
└── urls.py ← これ新規作成
$ vi sample_app/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
$ git add sample_app/urls.py
$ git commit -m 'アプリ用URLConfの新規作成'
↓ 在完成该操作后的目录结构
Django3.2-DRF
├── .git
├── .gitignore
├── README.md
├── config
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── sample_app
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ ├── models.py
│ ├── tests.py
│ ├── urls.py # 新規作成
│ └── views.py
└── venv
編輯路由用的URL配置
编辑的文件 de
Django3.2-DRF
└── config
└── urls.py ← これ
$ vi config/urls.py
现有文件之间的差异
$ git diff config/urls.py
diff --git a/config/urls.py b/config/urls.py
index 3a96dfd..a72a1f9 100644
--- a/config/urls.py
+++ b/config/urls.py
@@ -14,8 +14,9 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
-from django.urls import path
+from django.urls import path, include
urlpatterns = [
+ path('', include('sample_app.urls')),
path('admin/', admin.site.urls),
]
$ git add config/urls.py
$ git commit -m 'ルート用URLConfの編集'
只需一個選項,我將使用中文進行改寫:
啟動開發伺服器,並訪問 http://localhost:8000,如果顯示「Hello, world.」則表示正常。
$ python manage.py runserver
Django REST框架
使用Django REST Framework构建RESTful API后端
Django REST框架的安装
$ pip install djangorestframework django-filter
模型的定义
编辑的文件 de
Django3.2-DRF
└── sample_app
└── models.py ← これ
$ vi sample_app/models.py
from django.db import models
class Memo(models.Model):
title = models.CharField(max_length=64)
memo = models.TextField(max_length=1024)
$ git add sample_app/models.py
$ git commit -m 'sample_app のモデル定義'
建立数据库
$ python manage.py makemigrations
Migrations for 'sample_app':
sample_app/migrations/0001_initial.py
- Create model Memo
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sample_app, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sample_app.0001_initial... OK
Applying sessions.0001_initial... OK
$ git add sample_app/migrations/0001_initial.py
$ git commit -m 'python manage.py makemigrations'
↓ 這個工作完成後的目錄結構
Django3.2-DRF
├── .git
├── .gitignore
├── README.md
├── config
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3 # makemigrationsによって作成
├── manage.py
├── sample_app
│ ├── __init__.py
│ ├── __pycache__
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ ├── 0001_initial.py # makemigrationsによって作成
│ │ ├── __init__.py # makemigrationsによって作成
│ │ └── __pycache__ # makemigrationsによって作成
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── venv
在管理界面中添加sample_app模型。
编辑文件
Django3.2-DRF
└── sample_app
└── admin.py ← これ
$ vi sample_app/admin.py
from django.contrib import admin
from .models import Memo
@admin.register(Memo)
class MemoAdmin(admin.ModelAdmin):
pass
$ git add sample_app/admin.py
$ git commit -m '管理画面にsample_appのモデルを追加する'
可以登录管理界面以进行确认的用户和密码设置。
$ python manage.py createsuperuser
$ python manage.py runserver
Django REST Framework 的应用程序注册
编辑文件
Django3.2-DRF
└── config
└── settings.py ← これ
$ vi config/settings.py
与现有文件之间的差异
$ git diff config/settings.py
diff --git a/config/settings.py b/config/settings.py
index 0b0f505..3d3ec95 100644
--- a/config/settings.py
+++ b/config/settings.py
@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
+ 'rest_framework',
'sample_app',
'django.contrib.admin',
'django.contrib.auth',
$ git add config/settings.py
$ git commit -m 'Djagno REST Framework のアプリケーション登録'
序列化器的定义。
创建新文件
Django3.2-DRF
└── sample_app
└── serializer.py ← これ
$ vi sample_app/serializer.py
from rest_framework import serializers
from .models import Memo
class MemoSerializer(serializers.ModelSerializer):
class Meta:
model = Memo
fields = '__all__'
$ git add sample_app/serializer.py
$ git commit -m 'Serializerの定義'
通过这项工作可以创建的目录结构。
通过这个任务可以形成的目录结构。
Django3.2-DRF
├── .git
├── .gitignore
├── README.md
├── config
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3
├── manage.py
├── sample_app
│ ├── __init__.py
│ ├── __pycache__
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ ├── models.py
│ ├── serializer.py # 新規で作成
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── venv
添加ViewSet
编辑的文件
Django3.2-DRF
└── sample_app
└── views.py ← これ
$ vi sample_app/views.py
import django_filters
from django.shortcuts import render
from django.http import HttpResponse
from rest_framework import viewsets, filters
from .models import Memo
from .serializer import MemoSerializer
def index(request):
return HttpResponse("Hello, world.")
class MemoViewSet(viewsets.ModelViewSet):
queryset = Memo.objects.all()
serializer_class = MemoSerializer
$ git add sample_app/views.py
$ git commit -m 'ViewSetの定義'
编辑应用的URLConf
将设置集成到REST框架中。
编辑文件
Django3.2-DRF
└── sample_app
└── urls.py ← これ
$ vi sample_app/urls.py
与现有文件的差异
$ git diff sample_app/urls.py
diff --git a/sample_project/sample_app/urls.py b/sample_project/sample_app/urls.py
index 88a9cac..c4608a2 100644
--- a/sample_project/sample_app/urls.py
+++ b/sample_project/sample_app/urls.py
@@ -1,7 +1,13 @@
from django.urls import path
from . import views
+from rest_framework import routers
urlpatterns = [
path('', views.index, name='index'),
]
+
+router = routers.DefaultRouter()
+router.register(r'memo', views.MemoViewSet)
$ git add sample_app/urls.py
$ git commit -m 'REST frameworkの設定をアプリ用URLConfに組み込む'
编辑用于路由的URLConf
编辑文件
Django3.2-DRF
└── config
└── urls.py ← これ
$ vi config/urls.py
与现有文件的差异
$ git diff sample_project/urls.py
diff --git a/sample_project/sample_project/urls.py b/sample_project/sample_project/urls.py
index 8a17227..ab1c4f5 100644
--- a/sample_project/sample_project/urls.py
+++ b/sample_project/sample_project/urls.py
@@ -15,8 +15,10 @@ Including another URLconf
"""
from django.contrib import admin
from django.urls import path, include
+from sample_app.urls import router as sample_app_router
urlpatterns = [
path('', include('sample_app.urls')),
path('admin/', admin.site.urls),
+ path('api/', include(sample_app_router.urls)),
]
$ git add config/urls.py
$ git commit -m 'REST frameworkの設定をルート用URLConfに組み込む'
$ python manage.py runserver
请确认能够访问 http://localhost:8000/api/
骄傲自信
使用Django Rest Framework的代码生成Swagger文档。
安装Swagger(drf-spectacular)
由于Django REST Swagger已废弃,因此改用drf-spectacular
https://github.com/marcgibbons/django-rest-swagger
https://drf-spectacular.readthedocs.io/en/latest/
$ pip install drf-spectacular
启用Swagger
编辑的文件
Django3.2-DRF
└── config
└── settings.py ← これ
$ vi config/settings.py
% git diff config/settings.py
diff --git a/config/settings.py b/config/settings.py
index 51a848a..bc5ec3f 100644
--- a/config/settings.py
+++ b/config/settings.py
@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
+ 'drf_spectacular',
'rest_framework',
'sample_app',
'django.contrib.admin',
@@ -125,3 +126,13 @@ STATIC_URL = '/static/'
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+
+REST_FRAMEWORK = {
+ 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
+}
+
+SPECTACULAR_SETTINGS = {
+ 'TITLE': 'Swagger Sample App',
+ 'DESCRIPTION': 'https://qiita.com/mykysyk@github/items/fef6fb298393a029a5d4',
+ 'VERSION': '2022.5.20',
+}
$ git add config/settings.py
$ git commit -m 'swaggerの有効化'
編輯用於路由的URLConf。
Django3.2-DRF
└── config
└── urls.py ← これ
$ vi config/urls.py
与现有文件的差异
% git diff config/urls.py
diff --git a/config/urls.py b/config/urls.py
index cb9612c..f8f12d7 100644
--- a/config/urls.py
+++ b/config/urls.py
@@ -16,8 +16,12 @@ Including another URLconf
from django.contrib import admin
from django.urls import path, include
from sample_app.urls import router as sample_app_router
+from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
urlpatterns = [
+ path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
+ path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
+ path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
path('', include('sample_app.urls')),
path('admin/', admin.site.urls),
path('api/', include(sample_app_router.urls)),
$ git add config/urls.py
$ git commit -m 'swaggerの設定をルート用URLConfに組み込む'
尝试输出并启动 API 模式文件。
$ python manage.py runserver
JWT:只需要一个选项,请用汉语对下列文字进行释义:
使用JWT(JSON Web Token)来实现Web应用程序的身份验证引入。
安装djangorestframework-jwt
$ pip install djangorestframework-jwt
激活 djangorestframework-jwt
编辑文件
Django3.2-DRF
└── config
└── settings.py ← これ
$ vi config/settings.py
$ git diff config/settings.py
diff --git a/config/settings.py b/config/settings.py
index 9ff10dc..bdfd23c 100644
--- a/config/settings.py
+++ b/config/settings.py
@@ -129,6 +129,12 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
+ 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
+ 'DEFAULT_AUTHENTICATION_CLASSES': (
+ 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
+ 'rest_framework.authentication.SessionAuthentication',
+ 'rest_framework.authentication.BasicAuthentication',
+ )
}
$ git add config/settings.py
$ git commit -m 'JWTの有効化'
编辑根URLConf
Django3.2-DRF
└── config
└── urls.py ← これ
$ vi config/urls.py
与现有文件的差异
$ git diff config/urls.py
diff --git a/config/urls.py b/config/urls.py
index ffd781f..15c9fad 100644
--- a/config/urls.py
+++ b/config/urls.py
@@ -17,6 +17,7 @@ from django.contrib import admin
from django.urls import path, include
from sample_app.urls import router as sample_app_router
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
+from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
@@ -25,4 +26,5 @@ urlpatterns = [
path('', include('sample_app.urls')),
path('admin/', admin.site.urls),
path('api/', include(sample_app_router.urls)),
+ path('api-auth/', obtain_jwt_token),
]
$ git add config/urls.py
$ git commit -m 'JWTの設定をルート用URLConfに組み込む'
$ python manage.py runserver
确认
在没有令牌的情况下进行GET请求。
$ curl -XGET http://127.0.0.1:8000/api/memo/
{"detail":"Authentication credentials were not provided."}
发行代币
$ DJANGO_USERNAME='admin'
$ DJANGO_PASSWORD='userpassword'
$ curl -XPOST -d "username=${DJANGO_USERNAME}&password=${DJANGO_PASSWORD}" http://localhost:8000/api-auth/
{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNTg3MTM3OTc1LCJlbWFpbCI6IiJ9.uBKhe8ASSPaUXPVjMxxiuZsT4AIWq_8Nca9Hdk4NWRc"}
具有令牌的GET请求。
$ JWT=$(curl -XPOST -d "username=${DJANGO_USERNAME}&password=${DJANGO_PASSWORD}" http://localhost:8000/api-auth/ | jq -r .token)
$ curl -XGET -H "Authorization: JWT ${JWT}" http://127.0.0.1:8000/api/memo/
[]
提交数据进行注册
$ curl -XPOST -H "Authorization: JWT ${JWT}" http://127.0.0.1:8000/api/memo/ -d 'title=a&memo=a'
{"id":1,"title":"a","memo":"a"}
确认POST数据
$ curl -XGET -H "Authorization: JWT ${JWT}" http://127.0.0.1:8000/api/memo/
[{"id":1,"title":"a","memo":"a"}]
构建 Docker
创建新文件
Django3.2-DRF
├── Dockerfile ← 新規作成
└── requirements.txt ← 新規作成
$ vi Dockerfile
FROM python:3.10.4-alpine
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
RUN python3 -m venv /venv
ENV PATH=/venv/bin:$PATH
COPY ./ /code/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
$ pip freeze > requirements.txt
asgiref==3.5.2
attrs==21.4.0
Django==3.2.13
django-filter==21.1
djangorestframework==3.13.1
djangorestframework-jwt==1.11.0
drf-spectacular==0.22.1
inflection==0.5.1
jsonschema==4.5.1
PyJWT==1.7.1
pyrsistent==0.18.1
pytz==2022.1
PyYAML==6.0
sqlparse==0.4.2
uritemplate==4.1.1
尝试构建以确认图像是否正确创建。
$ docker build . -t django3.2
完成建造后,请先删除。
$ docker rmi django3.2
Docker-Compose的中文翻译是”容器编排”。
新建立的文件
Django3.2-DRF ← docker-composeコマンドはこのディレクトリで実行する
└── docker-compose.yml ← 新規作成
$ vi docker-compose.yml
version: '3'
services:
django:
container_name: django3.2
build: .
working_dir: /code
ports:
- "8000:8000"
command: >
sh -c "apk update &&
apk add bash &&
apk add git &&
python manage.py makemigrations &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000"
$ git add docker-compose.yml Dockerfile requirements.txt
$ git commit -m 'docker-compose対応'
$ docker-compose up -d
请确认您是否能够访问下方链接的URL。
GitHub (中文: GitHub)
搭建开发环境的下面命令可以随时在这里使用完成的源代码。
$ git clone https://github.com/mykysyk/Django3.2-DRF.git
$ cd Django3.2-DRF
$ docker-compose up -d
$ docker exec -i -t Django3.2-DRF-compose bash
bash-5.0# python manage.py createsuperuser
Docker Compose命令集
请参考
以下是一些资源链接,以中文为母语进行改写,只需要提供一个选项:
https://qiita.com/homines22/items/2730d26e932554b6fb58
https://www.django-rest-framework.org/tutorial/quickstart/
https://django-rest-swagger.readthedocs.io/en/latest/
https://docs.docker.com/compose/django/
https://jpadilla.github.io/django-rest-framework-jwt/