随着Python的普及和Vue.js的兴起,越来越多的开发人员希望将这两个框架一起使用来构建单页应用程序(SPA)。
我想出了一种在开发和生产环境中均可使用的Django-Vue集成策略。另外,它不需要额外的依赖关系。
我的方法涉及三个部分:
配置Vue以使用Django开发服务器进行本地开发,并在生产中使用Django生产服务器
配置Django以将Vue.js应用程序的生产模板作为其主页
配置Django和Vue在生产中提供Vue的静态文件(图像,CSS,JS)
让我们开始吧。
演示应用
好吧,也许我们还不会开始。 我在博客示例存储库中组合了一个演示应用程序,以展示如何在Django Web应用程序开发中使用Vue.js前端。
这是一个简单的Vue应用程序,显示了从Django API提取的短语列表:
作为参考,这是项目的简化文件结构,指定了下面提到的文件和目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
integrate-django-vuejs ├── django_vue/ │ └── settings.py # Django settings ├── frontend/ # Vue project │ ├── dist/ # Webpack build folder │ | ├── static/ # Vue assets | │ └── index.html # Vue HTML file │ ├── package.json # Node dependencies │ └── vue.config.js # Vue configuration ├── static/ # Django's collected static files │ ├── static/ # Vue's collected assets │ └── index.html # Vue's collected HTML file └── manage.py* |
开发环境
开发使用JSON API或任何API的Vue应用程序的技巧是确保Vue应用程序可以访问该API。 这听起来似乎很明显,但是由于开发API和生产API通常具有不同的URL,因此使API根URL保持直线可能很烦人。
我们要做的第一件事就是将Vue开发服务器配置为寻找API接口的Django服务器。
默认情况下,Django开发服务器在端口8000上运行,而Vue开发服务器在端口8080上运行。通过Vue的dev服务器代理设置,我们可以将Vue配置为在请求404时尝试另一个URL:
1 2 3 4 5 6 7 8 9 10 |
// vue.config.js module.exports = { devServer: { proxy: { '^/api/': { target: 'http://127.0.0.1:8000/api/', } } }, } |
完成此配置后,让我们进行API调用:
1 2 3 4 5 6 |
// This function uses vue-resource to help with API calls: // https://github.com/pagekit/vue-resource/ async fetchPhrases() { const response = await this.$http.get('/api/phrases/') return response.body.data } |
当我们向/ api / phrases /发出请求时,它将尝试获取localhost:8080 / api / phrases /,因为我们在API请求中省略了一个域。 该请求将为404,因此Vue将使用其开发服务器代理将请求代理到127.0.0.1:8000/api/phrases/,从而访问Django开发服务器。
非常好! Vue可以使用Django dev API,而不必大惊小怪不同的主机或端口。 现在,让他们在生产中一起工作。
生产
在生产中,Django负责繁重的工作。 它承载JSON API,并充当服务于Webpack构建的Vue应用程序的Web服务器。
为生产Vue配置Django
经过一些配置,我们可以使用Django的内置模板和静态文件支持来服务生产Vue应用程序。
让我们看一下该配置。
设定值
首先,Django设置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Directory where Django static files are collected STATIC_ROOT = os.path.join(BASE_DIR, 'static') # URL where static files will be served STATIC_URL = '/static/' # Vue project location FRONTEND_DIR = os.path.join(BASE_DIR, 'frontend') # Vue assets directory (assetsDir) STATICFILES_DIRS = [ os.path.join(FRONTEND_DIR, 'dist/static'), ] # Webpack output location containing Vue index.html file (outputDir) TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(FRONTEND_DIR, 'dist'), ], # Other TEMPLATE keys omitted for brevity }, ] |
此缩写的settings.py文件具有两点注意事项:
将Webpack内置资产目录frontend / dist / static添加到Django的包含静态文件的目录列表中
将Webpack构建目录添加到Django的模板路径中,以便Django可以找到生产index.html Vue模板
说到那个index.html文件,让我们做一个简单的视图来服务它,并在使用它时创建一个简单的API端点:
views.py
第一个视图呈现Production Vue应用程序模板。 第二个视图是适当API的替代,它返回JSON响应。
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# views.py from django.http import JsonResponse from django.shortcuts import render def index(request): return render(request, template_name='index.html') def simple_api_view(request): response = JsonResponse({ 'data': [ 'You get an phrase from the API!', 'And you get a phrase from the API!', 'And you get a phrase from the API!', 'And you get a phrase from the API!', 'And you get a phrase from the API!', ] }) return response |
我们也将注册这些视图。
URLs
1 2 3 4 5 6 7 8 |
from django.urls import path from django_vue.views import index, simple_api_view urlpatterns = [ path('', index, name='index'), path('api/phrases/', simple_api_view, name='phrases'), ] |
好的! 现在,只要Vue应用程序位于名为frontend的目录中,并且Webpack将构建的Vue应用程序放置在frontend / static /中,Django就会找到并服务于构建的Vue应用程序。
我们最好让Vue知道。
为生产Django配置Vue
设定值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// frontend/vue.config.js module.exports = { devServer: { proxy: { '^/api/': { target: 'http://127.0.0.1:8000/api/', ws: false, } } }, // outputDir must be added to Django's TEMPLATE_DIRS outputDir: './dist/', // assetsDir must match Django's STATIC_URL assetsDir: 'static', } |
以下是此配置的快速摘要:
配置说明
devServer.proxy将开发服务器API请求重定向到Django开发服务器
outputDir:’./dist/’指定Webpack将在哪里构建Vue应用程序
assetDir:“静态”将JS和CSS位置更新为Django服务它们的位置
assetDir:“静态”可能会受益于进一步的解释。
开箱即用,Vue的Webpack构建期望分别在/ css /和/ js / URL中找到其CSS和JS文件。 由于我们使用Django来提供这些文件,并且Django在STATIC_URL上提供静态文件,因此我们更新assetDir以匹配Django的静态URL。 在这种情况下,它是/ static /。
使用此设置,将使用指向Webpack构建的资源包(/ static / css /和/ static / js /)的正确路径来构建生产Vue index.html。
准备生产版本
首先,构建生产Vue.js构建:
1 2 |
cd frontend yarn build |
其次,将构建内容收集到Django的静态文件文件夹中:
1 |
./manage.py collectstatic |
启动前端项目:
1 2 |
cd frontend yarn run serve --host 0.0.0.0 --port 80 |
结论
只需进行少量配置,Django和Vue就可以在Web应用程序开发期间以及准备上线时很好地配合使用。
这种方法的第二个好处是,在开发新功能或修复错误时,您可以并行运行生产前端和开发前端,而Django的dev服务器运行生产版本,而Vue的dev服务器运行工作 -进行中。
这篇文章将Vue.js应用程序和Django API放到了一起,但这不是必须的。
使项目协同工作可能会很有趣,例如通过使Django视图满足Vue的index.html文件要求登录即可。
甚至有可能在Django和Vue之间共享模板部分。 毕竟,它们确实使用相同的{{variable}}语法。
原文:https://johnfraney.ca/posts/2019/05/14/integrate-django-vuejs/