让我们创建一个Django + Vue.js的开发环境

你想做什么?

本文档介绍了一种稍微不同的方法,使用Vue.js作为前端开发框架创建了一个单页面应用程序,并使用Django和Django REST框架作为后端,提供了Web API。虽然已经有一些先驱者使用了类似的解决方案,但我们试图尝试一种不同的方法,故特此撰写此文。

    • Django + Webpack を使ってVueを動かす

 

    Django REST framework with Vue.js

怎么做?

在Django项目中,通常会将html文件解释为模板并进行渲染,但是该模板语法与Vue非常相似。因此,带有Vue模板语法的html无法与Django模板共存。
因此,通过使用webpack将前端拆分为Vue的单文件组件,并编写代码来避免这个问题。由于Django模板和Vue在渲染时的时机不同,即在服务器端和客户端端分别进行渲染,因此通过将Vue部分作为组件从html文件中分离出来,可以使两者共存。也许还有更聪明的方法!

安装环境

使用Vue.js的Vuetify框架来实现前端,轻松地实现类似于Material Design的效果。只需使用vue-cli,就能快速设置一个使用webpack的前端项目。真方便!请先安装npm。项目名称随意,这里我们将其命名为miniblog。

% npm i -g vue-cli
% vue init vuetifyjs/webpack miniblog

如果没有特殊要求,你可以直接按Enter键,无需更改任何设置。完成后,立即使用npm run dev命令启动webpack开发服务器,并打开http://localhost:8080/,你应该能看到示例显示出来。

首先,我们创建一个Django项目。首先,在virtualenv中创建一个Python3的虚拟环境并安装Django。由于Django2.0不支持Python2,所以如果使用Python2,请使用较旧的版本。请预先安装好virtualenv。虚拟环境的名称可以随意取,这里我们使用venv。

% cd miniblog/
% virtualenv -p /path/to/python3 venv
% . venv/bin/activate
(venv) % pip install django djangorestframework

创建一个Django项目,并将miniblog目录直接作为项目根目录。顺便添加一个名为entry的Django应用程序。

(venv) % django-admin startproject miniblog .
(venv) % django-admin startapp entry

完成后,在终端输入python manage.py runserver以启动Django开发服务器,在浏览器中打开http://localhost:8000/,应该会显示启动页。现在一切所需已准备就绪。

改變環境

我們將調整webpack的設定,將生成的靜態資源放置在Django指定的目錄中。我們將編輯config/index.js檔案。

...

module.exports = {
  dev: {

    ...
    proxyTable: {
      '/api' : {
        target: 'http://localhost:8000',
        changeOrigin: true,
        pathRewrite: {  // 開発サーバーでもDjangoのAPIにアクセスできるように設定
          '^/api': 'api'
        }
      }
    },

    ...
    // デフォルトのSourceMapは相対パスを参照しているらしく、この環境ではバグになる。
    cssSourceMap: false,
  },

  build: { // コンパイルされたファイルをDjangoの所定位置へ
    // Template for index.html
    index: path.resolve(__dirname, '../templates/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../static'),
    assetsSubDirectory: 'build',
    assetsPublicPath: '/static/',

    ...
  }
}

环境本身已经完成,接下来需要一些Django的配置,我们将通过测试来完成。

创建一个API

我将创建一个简单的博客API。顺便说一下,我还会完成由webpack生成的单页面应用的路由功能。首先,我需要在配置中添加一些内容。

INSTALLED_APPS = [
    ~

    # 追記
    'rest_framework',
    'entry',
]

~
TEMPLATES = [
    {
        'DIRS': [ # webpackはindex.htmlをtemplatesディレクトリに生成する
            os.path.join(BASE_DIR, 'templates'),
        ],
    },
]

~

# webpackは先の設定でstaticディレクトリにcssとjsファイルを生成する
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

接下来,我会写出模型。

class Entry(models.Model):
    title = models.CharField(max_length=200)
    contnt = models.TextField()
    date = models.DateField()

接下来,在entry/中添加serializers.py文件,并按照下面的方式进行编辑。

from rest_framework import serializers
from .models import Entry

class EntrySerializer(serializers.ModelSerializer):
    class Meta:
        model = Entry
        fields = (
            'id',
            'title',
            'content',
            'date'
        )

此外,在views.py文件中,还需要添加以下内容。

from rest_framework import generics
from rest_framework.permissions import AllowAny
from .models import Entry
from .serializers import EntrySerializer


class EntryListAPIView(generics.ListAPIView):
    permission_classes = (AllowAny,)
    serializer_class = EntrySerializer
    queryset = Entry.objects.all()

将以下类似的urls.py文件添加到entry/目录中。

from django.urls import path
from .views import EntryListAPIView


urlpatterns = [
    path('entries/', EntryListAPIView.as_view()),
]

请在entry/admin.py文件中添加以下内容。

from django.contrib import admin
from .models import Entry


admin.site.register(Entry)

再写一点!在miniblog/urls.py中添加。

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from .views import index

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('entry.urls')), # APIへのルーティング
    path('', index, name='index'), # vueシングルページアプリへのルーティング
] + static(settings.STATIC_URL) # staticディレクトリにルーティング

我要在miniblog/views.py中最后加上一行代码。

from django.shortcuts import render


# webpackが生成したhtmlをそのままテンプレートとして読み込ませる
def index(request):
    return render(request, 'index.html', {})

终于完成了!在确认之前,不要忘记进行Entry模型的迁移。

(venv) % python manage.py makemigrations
(venv) % python manage.py migrate

通过这样配置后,我们已经基本上实现了一个类似于API的功能。您可以通过在命令行中使用 “python manage.py createsuperuser” 命令添加管理员用户,然后使用 “python manage.py runserver” 命令启动开发服务器,并访问管理员页面来添加一些条目。之后,当您访问”http://127.0.0.1:8000/api/entries/”时,应该会返回一份以JSON格式呈现的Entry模型列表。有很多地方可以进行修改呢。
其实最好还是写一些CRUD和测试之类的,但这不是我们的重点,就算到这儿吧。
这样,Django的配置就完成了。

尝试使用Vue.js读取API数据。

终于到Vue了。使用axios来处理API的请求。快速安装。

% npm i --save axios

完成后,我们来编写Vue的代码。由于应该已经有了Vuetify的演示代码,我们将对其进行编辑。

<template>
  <v-container fluid grid-list-md>
    <v-slide-y-transition mode="out-in">
      <v-layout row wrap align-center>
        <v-flex v-for="entry in entryList">
          <v-card>
            <v-card-title>
              <span class="headline">{{ entry.title }}</span>
            </v-card-title>
            <v-card-text>
              <blockquote>
                {{ entry.content }}
                <footer>
                  <small>
                    <em>&mdash;{{ entry.date }}</em>
                  </small>
                </footer>
              </blockquote>
            </v-card-text>
          </v-card>
        </v-flex>
      </v-layout>
    </v-slide-y-transition>
  </v-container>
</template>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<script>
import axios from 'axios'

export default {
  data () {
    return {
      entryList: []
    }
  },
  mounted: function () {
    console.log('mounted')
    // APIを叩く。
    // 開発サーバで動作中はちゃんとDjangoの8000番ポートを叩いてくれます。
    axios.get('/api/entries/')
      .then((response) => {
        this.entryList = response.data
      })
      .catch((error) => {
        console.log(error)
      })
  }
}
</script>

成功了!在执行npm run build之后,再使用django manage.py runserver命令启动开发服务器,然后在http://127.0.0.1:8000/上应该会显示以Entry模型形式排列的内容。API工作正常!

这个环境的优点

我个人认为这个开发环境最棒的地方是可以同时启动Django开发服务器和webpack开发服务器,从而在前端和后端开发中都能享受热重载的好处。只需编写代码,就能立即反映在页面上,无需重新加载浏览器!此外,虽然Django模板也可以共存,但如果使用Vue创建单页应用,老实说Django模板就没有什么优势了。

总结

Django和Vue.js的开发环境已经准备好了。只是在webpack的配置中稍作修改,并没有进行太过任性的设置,所以扩展也应该很容易。不过项目有点杂乱可能是个小问题。再努力一点的话,似乎可以整理好了。
总之,现在可以尽情地在Django和Vue.js上玩了!

我已经在GitHub上准备了一个可以实际运行的项目,这里是链接。

广告
将在 10 秒后关闭
bannerAds