Этот пост будет:

  • Покажем, как развернуть интегрированное веб-приложение Django (backend API) и Vue.js (frontend SPA) на одном сервере Python Heroku. Одностраничное приложение (SPA) Vue.js будет построено с использованием сборщика модулей Webpack. Отдельные URL-пути будут открывать SPA (например, https://django-vue-template.herokuapp.com/) и API Django (например, https://django-vue-template.herokuapp.com/api_example/ ).
  • Продемонстрируйте, как настроить переменные среды Webpack для автоматической обработки запросов API при разработке и производстве.

Репозиторий GitHub, содержащий заполненный шаблон, можно найти здесь

Недавно я приступил к созданию веб-приложения Django и Vue.js для развертывания на сервере Python Heroku. В качестве бэкэнда я выбрал Django, поскольку он позволяет легко интегрировать многочисленные библиотеки машинного обучения Python. Vue.js был выбран для внешнего интерфейса, потому что это простой компонентный и реактивный фреймворк с отличной документацией. По своему личному опыту могу гарантировать, что для ознакомления с его основными концепциями требуется минимум времени. Кроме того, количество звезд Vue.js на GitHub недавно обогнало React, и его экосистема быстро расширяется:

Шаг 1 - Настройте Django:

Во-первых, настройте и активируйте виртуальную среду Python, запустив conda create --name django_vue_template python=3, а затем_2 _. *

* В этом абзаце описывается, как настроить виртуальную среду Python с помощью Conda. Однако вы можете свободно настраивать виртуальную среду Python как обычно.

После активации виртуальной среды запустите pip install django, затем _4 _ ** и, наконец, cd django_vue_template. Теперь вы должны находиться в корне шаблона проекта Django.

** Этот проект называется «django_vue_template», но вы можете свободно называть свой проект как угодно; просто замените название своего проекта на «django_vue_template» везде, где оно будет позже в этом сообщении.

Шаг 2 - Настройте Vue.js с помощью Webpack:

В этом руководстве предполагается, что у вас уже установлены инструменты Vue CLI. В противном случае их можно очень просто установить, запустив npm install -g vue-cli.

Из корня шаблона проекта Django запустите vue init webpack, а затем ответьте на следующие запросы следующим образом:

  • «Создать проект в текущем каталоге?» - Y
  • «Сборка Vue» - среда выполнения + компилятор: рекомендуется для большинства пользователей.
  • «Следует ли запускать для вас npm install после создания проекта? (рекомендуется) » - Да, использовать NPM

На все остальные запросы ответьте так, как хотите; это не важно для этого урока. После этого файловая структура должна выглядеть примерно так:

Шаг 3 - Настройте URL-адрес Django для рендеринга Vue.js SPA:

Чтобы настроить Django для рендеринга Vue.js SPA, в корневом каталоге проекта сначала запустите npm run build. Это создаст каталог с именем / dist /, содержащий шаблон index.html, который является готовой к производству версией Vue.js SPA.

Во-вторых, в файле настроек Django (/django_vue_template/settings.py) добавьте каталог / dist / как место, в котором Django может искать index.html шаблон. Для этого добавьте os.path.join (BASE_DIR, ‘dist’) в список DIRS в настройке TEMPLATES следующим образом:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'dist')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Затем определите местоположение, по которому приложение staticfiles должно проходить, если запущен collectstatic (это произойдет автоматически при развертывании приложения в Heroku), добавив следующий код в файл настроек Django (/django_vue_template/settings.py):

STATICFILES_DIRS = [
  os.path.join(BASE_DIR, 'dist/static'),
]

Наконец, отредактируйте /django_vue_template/urls.py, чтобы Django отображал шаблон SPA index.html Vue.js, расположенный в / dist /, когда запрос делается на корневой URL. Сделайте это, отредактировав /django_vue_template/urls.py так, чтобы он выглядел так:

Теперь, когда сервер разработки Django запускается путем выполнения python manage.py runserver, шаблон приложения проекта Vue.js по умолчанию должен отображаться по адресу http: // localhost: 8000 /.

Шаг 4 - Настройте простой Django API:

Чтобы продемонстрировать, как выполнять запросы данных к API серверной части Django из Vue.js SPA, необходимо настроить пример API JSON. Для этого запустите python manage.py startapp api_example из корня проекта, затем замените содержимое файла /api_example/views.py на:

Во-вторых, добавьте файл urls.py в каталог / api_example /, содержащий:

Наконец, отредактируйте /django_vue_template/urls.py так, чтобы он выглядел так:

Теперь, когда сервер разработки Django запускается путем выполнения python manage.py runserver, должен быть обнаружен очень простой API, который при вызове отвечает базовым объектом JSON - {names: [William, Rod, Grant]}. по адресу http: // localhost: 8000 / api_example /.

Шаг 5. Запросите данные API Django из Vue.js SPA:

Теперь, когда базовый JSON API настроен, мы можем создать базовый Vue.js SPA, который отправляет к нему запросы. Для этого удалите каталоги / assets / и / components / из каталога / src /. Теперь файловая структура должна выглядеть примерно так:

Затем установите axios (HTTP-клиент для браузера и node.js, который будет использоваться для выполнения запросов), запустив npm install axios --save из корня проекта.

Теперь создайте базовый Vue.js SPA, отредактировав /src/App.vue так, чтобы он выглядел так:

Наконец, запустите npm run build из корня проекта, чтобы обновить каталог / dist / с готовой к эксплуатации версией нового Vue.js SPA.

На этом этапе, когда сервер разработки Django запускается путем выполнения python manage.py runserver, очень простой Vue.js SPA должен располагаться по адресу http: // localhost: 8000 /, который будет Выбрать победителя при нажатии кнопки.

Шаг 6 - Настройте переменные среды Webpack и для разработки и производства:

Разработать Vue.js SPA с помощью сборщика модулей Webpack - это здорово, так как он поставляется со встроенным сервером разработки, позволяющим разработчикам просматривать изменения в своем внешнем коде в своем браузере в режиме реального времени.

Однако, когда вы запускаете сервер разработки Webpack, запустив npm run dev из корня проекта, вы заметите, что он запускается через отдельный порт для сервера разработки Django.

Это проблема, потому что Vue.js SPA в настоящее время написан для запроса данных API из корневого URL + /api_example/:

FetchData: function() {
          .....
          axios.get("/api_example/").then(.....);
      },

Следовательно, при использовании сервера разработки Webpack Vue.js SPA отправляет запрос на http: // localhost: 8080 / api_example /, а это не то место, где расположен JSON API. Это означает, что СПА не работает, и нельзя выбрать победителя.

К счастью, используя переменные среды Webpack, Vue.js SPA может быть настроен на отправку запросов в разные места в процессе производства и разработки.

Чтобы настроить их, сначала отредактируйте /config/dev.env.js так, чтобы он выглядел так:

Во-вторых, отредактируйте /config/prod.env.js так, чтобы он выглядел так:

В-третьих, отредактируйте метод FetchData () в /src/App.vue так, чтобы он выглядел так:

FetchData: function() {
          var app = this;
          axios.get(process.env.API_URL + "/api_example/").then(response => {
              app.names = response.data.names;
          });
      }

Наконец, запустите npm run build. Vue.js SPA теперь будет делать запросы к корневому URL + /api_example/ в рабочей среде и http: // localhost: 8000 / api_example / при использовании сервера разработки Webpack.

Шаг 7 - Разрешите совместное использование ресурсов из разных источников в процессе разработки:

Запустите серверы разработки Django и Webpack одновременно в двух отдельных окнах эмулятора из корня проекта, запустив соответственно python manage.py и npm run dev. Вы заметите, что Vue.js SPA, обслуживаемый сервером разработки Webpack по адресу http: // localhost: 8080 /, по-прежнему не может успешно запросить данные из JSON API, расположенного по адресу http: // localhost: 8000 / api_example . Это связано с тем, что серверная часть Django не настроена локально для разрешения совместного использования ресурсов из разных источников с http: // localhost: 8080.

Чтобы решить эту проблему, добавьте в проект библиотеку django-cors-headers, запустив pip install django-cors-headers, затем добавьте corsheaders в INSTALLED _APPS в /django_vue_template/settings.py следующим образом :

INSTALLED_APPS = (
    .....
    'corsheaders',
    .....
)

Затем добавьте corsheaders.middleware.CorsMiddleware в параметр MIDDLEWARE в /django_vue_template/settings.py. Это должно быть выше "django.middleware.common.CommonMiddleware", например:

MIDDLEWARE = [
    .....
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    .....
]

Поскольку мы хотим разрешить перекрестный источник ресурсов только с http: // localhost: 8080 локально, добавьте следующий параметр в файл /django_vue_template/settings.py:

CORS_ORIGIN_ALLOW_ALL = False

После этого в самом низу вставки файла /django_vue_template/settings.py:

try:
    from local_settings import *
except ImportError:
    pass

Приведенный выше оператор попытается импортировать дополнительные настройки, хранящиеся в файле /local_settings.py, если он присутствует, и передать, если он не существует. Чтобы воспользоваться этим, в корне проекта создайте файл local_settings.py, содержащий:

Когда серверы разработки Django и Webpack теперь запускаются одновременно, должна быть полностью функционирующая версия Vue.js SPA, обслуживаемая сервером разработки Webpack, расположенным по адресу http: // localhost: 8080 /.

Шаг 8 - Настройте и разверните на сервере Heroku:

Перед развертыванием приложения на Heroku необходимо настроить еще пару элементов. Во-первых, добавьте в проект Gunicorn и WhiteNoise, запустив pip install gunicorn whitenoise.

Gunicorn работает как HTTP-сервер Python WSGI для UNIX, а Whitenoise позволяет приложению обслуживать свои собственные статические файлы при развертывании, поскольку Django не поддерживает это в производственной среде.

На этом этапе, поскольку больше пакетов Python добавляться не будет, имеет смысл создать файл /requirements.txt, в котором перечислены все те, от которых зависит проект. Сделайте это, запустив pip freeze > requirements.txt из корня проекта.

Затем необходимо настроить Whitenoise, отредактировав файл /django_vue_template/wsgi.py так, чтобы он выглядел следующим образом:

Чтобы убедиться, что в Heroku не развернуты локальные ресурсы, которых не должно быть, замените содержимое файла /.gitignore на:

Затем добавьте файл с именем Procfile в корень проекта. Он определяет команды, которые выполняются дино приложения при развертывании на Heroku, и в этом случае должен содержать:

При развертывании в Heroku рекомендуется использовать переменные среды, чтобы конфиденциальная информация не хранилась непосредственно в вашем коде. В случае этого проекта это следует настроить локально, создав файл .env в корне проекта, содержащий:

При работе над этим разрабатываемым проектом сейчас source .env нужно будет сначала запустить из корня проекта, чтобы настроить переменные среды.

Следуя этим шагам, посетите Heroku.com и создайте новое приложение. Затем перейдите на вкладку Настройки приложения и добавьте пакеты сборки heroku / nodejs и heroku / python, убедившись, что они перечислены в следующем порядке:

Пакет сборки Python должен быть указан вторым, поскольку Heroku использует последний пакет сборки для определения типов процессов для приложения.

Затем запишите домен, в котором будет расположено приложение (также указанный на вкладке «Настройки»), и отредактируйте переменные конфигурации, чтобы они содержали переменную среды SECRET_KEY следующим образом:

Теперь вернитесь в локальный проект и настройте параметры DEBUG, SECRET_KEY и ALLOWED_HOSTS в /django_vue_template/settings.py следующим образом:

DEBUG = False
SECRET_KEY = os.environ['SECRET_KEY']
ALLOWED_HOSTS = ['django-vue-template.herokuapp.com', 'localhost']

Вместо «django_vue_template.herokuapp.com» укажите домен Heroku, на котором будет расположено ваше приложение, который вы записали ранее

Затем добавьте параметры STATIC_ROOT (абсолютный путь к каталогу, в котором collectstatic будет собирать статические файлы для развертывания) и STATICFILES_STORAGE (механизм хранения файлов, используемый при сборе статических файлов с помощью команды управления collectstatic) в django_vue_template / settings. py вот так:

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

Теперь добавьте «postinstall»: «npm run build» к объекту сценариев /package.json, чтобы Node.js знал, что нужно создавать Vue.js SPA при развертывании, как это:

"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "node build/build.js",
    "postinstall": "npm run build"
  }

Затем отправьте весь проект на GitHub обычным способом, а затем сделайте ссылку на соответствующий репозиторий на вкладке «Развертывание» приложения Heroku следующим образом:

Наконец, разверните приложение, нажав «Развернуть ветвь»:

Надеюсь, этот пост был вам полезен. Пожалуйста, не стесняйтесь комментировать любые мысли!