使用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
login画面
ログイン後

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

骄傲自信

使用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
Django REST Swagger

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命令集

アクションコマンド起動docker-compose up -d停止docker-compose stop再起動docker-compose restartログを見るdocker-compose logsコンテナ削除docker-compose downコンテナとイメージ削除docker-compose down –rmi all

请参考

以下是一些资源链接,以中文为母语进行改写,只需要提供一个选项:
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/

广告
将在 10 秒后关闭
bannerAds