我尝试实现了Nuxt.js前端与Django后端之间的API协作
首先
我是第一次投稿。
最近我对Web开发很感兴趣,正在学习各种知识。
在这篇文章中,我将介绍一个使用Django构建后端部分、使用Nuxt.js构建前端部分的项目,
并将重点放在开发环境中的可用性上。
准备

环境
Windows10 专业版
Docker 桌面版 v2.1.0.5
Python 3.6.9
Django 2.2.7
Django Rest Framework 3.10.3
MySQL 版本 8.0.17
Nuxt.js v2.11.0
目录结构
.
├─django
│ ├─manage.py
│ ├─composeexample
│ │ ├─settings.py
│ │ ├─urls.py
│ │ ├─wsgi.py
│ │ └─__init__.py
│ └─myapp
│ ├─migrations
│ ├─admin.py
│ ├─apps.py
│ ├─models.py
│ ├─renderers.py
│ ├─serializers.py
│ ├─tests.py
│ ├─urls.py
│ ├─views.py
│ └─__init__.py
│
├─docker-compose.yml
│
├─dockerfiles
│ ├─django_docker
│ │ ├─dockerfile
│ │ └─requirements.txt
│ └─nuxt_docker
│ └─dockerfile
│
├─mysql
│ └─conf.d
│
└─nuxt
└─front
└─以下略
各种文件
version: '3'
services:
db:
image: mysql:latest
restart: always
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: test
MYSQL_USER: test
MYSQL_DATABASE: test
MYSQL_PASSWORD: test
ports:
- 3306:3306
expose:
- 3306
volumes:
- mysqldata:/var/lib/mysql
- ./mysql/conf.d:/etc/mysql/conf.d
web:
container_name: django
build: ./dockerfiles/django_docker
command:
python3 manage.py runserver 0.0.0.0:8000
volumes:
- ./django:/code
ports:
- "8000:8000"
depends_on:
- db
front:
container_name: nuxt
build: ./dockerfiles/nuxt_docker
tty: true
volumes:
- ./nuxt:/code
ports:
- "3000:3000"
volumes:
mysqldata:
# ベースイメージを指定
FROM python:3.6-stretch
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
# ディレクトリを移動する
WORKDIR /code
# pipでrequirements.txtに記載のパッケージをインストール
COPY requirements.txt /code/
RUN pip3 install -r requirements.txt
COPY . /code/
※Django的映像是通过stretch构建的,原因是与Open SSH的密钥长度有关。请参考此处。
Django>=2.0,<3.0
djangorestframework
django-webpack-loader
django-cors-headers
mysqlclient
在requierment.txt文件中记录需要的Python包。除了Django,还需要安装与API相关的其他包。
以下是Django REST框架所需的组件:
– djangorestframework
– django-webpack-loader
– django-cors-headers
以下是使用Django连接MySQL所需的必备组件之一:mysqlclient。
# ベースイメージを指定
FROM node:latest
RUN mkdir -p /code
# node.js の環境変数を定義する
# 本番環境では production
ENV NODE_ENV=development
# yarnとaxiosをinstall
RUN yarn install
RUN yarn add @nuxtjs/axios
# ディレクトリを移動する
WORKDIR /code
# ポート3000番を開放する
EXPOSE 3000
Django的建立
创建项目
我正在参考这篇文章。
学习如何迅速掌握Django的第一部分。
通过Docker创建Django的开发环境(快速入门:Compose和Django的MySQL版)。
【Django】添加应用程序的步骤。
首先使用docker-compose启动容器。使用MySQL来建立它。
> docker-compose up -d db
可以用 docker ps 命令确认。
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
285cf6b8473b mysql:latest "docker-entrypoint.s…" 2 minutes ago Up 4 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
接下来,我们将使用docker-compose来启动容器。由于这是初次操作,我们也会执行构建操作。
> docker-compose up -d --build
我将创建一个Django项目(项目名称任意)。
> docker-compose run web django-admin.py startproject composeexample .
这个部分将会被生成。
.
└─django
├─manage.py
└─composeexample
├─settings.py
├─urls.py
├─wsgi.py
└─__init__.py
接下来,我们将编辑setting.py文件。
默认情况下,它使用SQLite数据库,我们将其更改为MySQL。
#<変更前>
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
#上記を↓↓↓に変更
#ユーザ名やパスは適宜変更してください
#<変更後>
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test',
'USER': 'test',
'PASSWORD': 'test',
'HOST': 'db',
'PORT': '3306',
}
}
接下来将进行联合DB的迁移。
> docker-compose run web ./manage.py migrate
创建超级用户。
> docker-compose run web ./manage.py createsuperuser --username admin --email admin@localhost
Starting mysql ... done
Password: #パスワードを聞かれるので入力
Password (again): #再度入力
The password is too similar to the username.
This password is too short. It must contain at least 8 characters.
This password is too common. #パスワードが短いと警告が出る
Bypass password validation and create user anyway? [y/N]: y #yを入力
Superuser created successfully.
我将在这里尝试启动Django的开发服务器。
使用docker-compose up -d命令,所有在docker-compose.yml中定义的容器将在后台启动。
(Nuxt的容器也会在这个阶段启动)
> docker-compose up -d
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
746b29edf07b working_web "python3 manage.py r…" 30 hours ago Up 30 hours 0.0.0.0:8000->8000/tcp django
0ae9f6506532 mysql:latest "docker-entrypoint.s…" 30 hours ago Up 30 hours 3306/tcp, 33060/tcp, 0.0.0.0:3306->3306/tcp mysql
0107b2a7301b working_front "docker-entrypoint.s…" 30 hours ago Up 30 hours 0.0.0.0:3000->3000/tcp nuxt
由于django开发服务器正在监听端口8000,
我们尝试访问http://localhost:8000/admin。
对应于./docker-compose.yml中的以下部分。
#~略~
command:
python3 manage.py runserver 0.0.0.0:8000
#~略~


创建应用程序
接下来,我们将生成应用程序的部分。(应用程序的名称可以自由选择)
> docker-compose run web ./manage.py startapp myapp
这部分将被生成。
.
└─django
└─myapp
├─migrations
├─admin.py
├─apps.py
├─model.py
├─tests.py
├─view.py
└─__init__.py
在setting.py中添加创建的应用程序。
如果不这样做,Django上生成的应用程序将无法被识别。
# ~略~
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp', #追加
]
# ~略~
我們將在生成的models.py文件中進行模型的附加。
首先,我們創建一個簡單的Person_data模型。
該模型只包含人的姓名和年齡。
將此內容寫在這裡,通過遷移操作,將在MySQL上創建相應的表。
from django.db import models
# Create your models here.
class Person_data(models.Model):
person_name = models.TextField()
person_age = models.IntegerField()
如果您新增了應用程式,則需要執行makemigrations。
> docker-compose run web ./manage.py makemigrations
> docker-compose run web ./manage.py migrate
您可以通过在admin.py文件中添加以下内容来从管理界面查看已创建的模型。
from django.contrib import admin
from .models import Person_data #作成したモデルをimport
# Register your models here.
admin.site.register(Person_data) #作成したモデルを追記



你可以在MySQL上确认下面的内容。
> docker exec -it mysql /bin/bash #MySQLコンテナに入る
> mysql -u test -p #MySQL起動
Enter password: #本記事の例だとtestでログイン可能
> use test;
> select * from myapp_person_data;
+----+-------------+------------+
| id | person_name | person_age |
+----+-------------+------------+
| 1 | takashi | 26 |
| 2 | naoto | 32 |
| 3 | tomoko | 15 |
+----+-------------+------------+
3 rows in set (0.00 sec)
Django的准备工作到此结束。
构建Django REST框架
在准备好Django之后,接下来我们将在Django中创建API。
我们将创建一个简单的API,只使用GET方法来获取上述表格的内容。
首先,在setting.py文件中添加以下内容。
这里参考了以下内容:
尝试使用Django REST Framework创建API
总结了使用Django REST Framework实现API服务器的经验和知识(还包括OAuth)
# ~略~
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
'rest_framework', #追加
]
# ~略~
通过添加’rest_framework’,可以使用Django REST framework的功能。
然后,手动创建Serializer.py、Renderer.py和urls.py(在我的应用程序下),并添加以下内容。
.
└─django
└─myapp
├─migrations
├─admin.py
├─apps.py
├─model.py
├─tests.py
├─view.py
├─renderers.py #これ
├─serializers.py #これ
├─urls.py #これ
└─__init__.py
from rest_framework import serializers
from .models import Person_data
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person_data
fields = '__all__'
import json
from rest_framework.renderers import JSONRenderer
class PersonJSONRenderer(JSONRenderer):
charset = 'utf-8'
def render(self, data, accepted_media_type=None, renderer_context=None):
return json.dumps({'person_data': data},ensure_ascii=False)
from django.urls import path
from .views import PersonListApiView
urlpatterns = [
path('get_person/', PersonListApiView.as_view()),
]
编辑composeexample文件夹下的urls.py,并启用myapp文件夹下的urls.py。
"""composeexample URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include # includeを追加
from myapp import urls # myapp配下のurls.pyをimport
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(urls), # 追加
]
我要编辑view.py文件。
from django.shortcuts import render
from django.views.generic import ListView
from myapp.models import Person_data
from rest_framework import status
from rest_framework.generics import ListAPIView
from rest_framework.permissions import AllowAny
from .renderers import PersonJSONRenderer
from .serializers import PersonSerializer
# Create your views here.
class PersonListApiView(ListAPIView):
model = Person_data # モデルを指定
queryset = Person_data.objects.all()
permission_classes = (AllowAny, )
renderer_classes = (PersonJSONRenderer, ) # Rendererを指定
serializer_class = PersonSerializer # Serializerを指定
在settings.py文件中添加以下内容。
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}

使用Nuxt.js获取API结果。
已经完成了Django端的API,现在要开始构建前端。
参考了以下内容。
理解Nuxt.js和Vue.js的基本用法。
Nuxt.js官方网站。
首先进入Nuxt.js的容器,创建一个项目(项目名称可以任意)。
在输入 “yarn create nuxt-app front” 之后,选择基本上都采用了默认值,只是将渲染模式设置为单页面应用程序。
这里的设置可以在以后的 “nuxt.config.js” 文件中进行更改。
> docker exec -it nuxt /bin/bash
> yarn create nuxt-app front
? Project name front
? Project description My doozie Nuxt.js project
? Author name
? Choose the package manager Yarn
? Choose UI framework None
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Choose linting tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Choose test framework None
? Choose rendering mode Single Page App
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
如果下列内容显示出来,就表示完成了。
? Successfully created project front
To get started:
cd front
yarn dev
To build & start for production:
cd front
yarn build
yarn start
Done in 167.32s.
在运行开发服务器之前,需要在nuxt.config.js中添加代码以进行确认。
在docker上运行nuxt.js时,需要以下内容。请参考。
export default {
mode: 'spa',
//ここから
server: {
port: 3000,
host: '0.0.0.0',
},
//ここまでを追記
/*
** Headers of the page
*/
我将尝试运行开发服务器。在完成后的消息中也有提到,您需要进入容器内创建的项目文件夹,然后运行”yarn dev”命令。
> cd front
> yarn dev

在从这里开始编辑时启用热重载。
如果要在Docker上进行开发,则需要明确指定。
请参考如下所示,在文件末尾添加以下内容。
export default {
//~略~
}, //追記の際はこのカンマを忘れずに
watchers: {
webpack: {
poll: true
}
}
}
接着我们将添加axios的设置。
axios是一个在node.js中运行的HTTP客户端,我们将使用它从nuxt.js中调用之前提到的API的URL。
由于在前面提到的nuxt的dockerfile中已经包含了这些内容,所以axios已经安装在容器中。
我们将在modules中添加以下内容,并添加axios。
export default {
//~略~
modules: [
'@nuxtjs/axios',
],
axios: {
baseURL: "http://localhost:8000"
},
//~略~
为了简化操作,我们将编辑首页。
接下来,我们将对实际页面进行编辑。
<template>
<div class="container">
<div>
<logo />
<h1 class="title">
front
</h1>
<h2 class="subtitle">
My doozie Nuxt.js project
</h2>
<div class="links">
<a
href="https://nuxtjs.org/"
target="_blank"
class="button--green"
>
Documentation
</a>
<a
href="https://github.com/nuxt/nuxt.js"
target="_blank"
class="button--grey"
>
GitHub
</a>
<!-- ここから追記 -->
<div v-for="d in dat.person_data" :key=d.person_name align="center">
<h2>
{{d.person_name}} {{d.person_age}}
</h2>
</div>
<!-- ここまで追記 -->
</div>
</div>
</div>
</template>
<script>
import Logo from '~/components/Logo.vue'
export default {
components: {
Logo
},
//ここから追記
data() {
return {
dat: []
}
},
async mounted(){
const url = "/api/get_person/"
const response = await this.$axios.get(url)
this.dat = response.data
}
//ここまで追記
}
</script>
//~略~
由于这样的话会遇到CORS问题,所以需要调整django的设置。将其添加到setting.py中。
# ~略~
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
'rest_framework',
'corsheaders', #追加
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 追加
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# ~略~
### 末尾に下記を追加
# 許可するオリジン
CORS_ORIGIN_WHITELIST = [
'http://localhost:3000',
]
# レスポンスを公開する
CORS_ALLOW_CREDENTIALS = True

最后
我已经通过API实现了Django和Nuxt.js的简单集成。以上是开发环境的内容,我认为可能需要进行调整以用于生产环境。为了学习目的,我现在先发布此阶段的内容。