Как я построил проект на Django, Django REST Framework, Angular 1.1.x и Webpack - Блог ITVDN
ITVDN: курсы программирования
Видеокурсы по
программированию

Выбери свою IT специальность

Подписка

Как я построил проект на Django, Django REST Framework, Angular 1.1.x и Webpack

advertisement advertisement

Моя идея состояла в том, чтобы построить простой репликабельный проект на Angular с бэкэндом на Django. Я искал и не смог найти нужных решений, пришлось во всем разбираться самому. В итоге я разобрался и решил сам написать гайд для всех, кого может заинтересовать данная проблема. 
Данная статья поможет вам построить простое приложение Angular с бэкэндом на Django, организованного с помощью Webpack.


Проблема

Я хочу настроить проект на Angular 1.1.x и скормить ему данные с сервера Django. Мне бы хотелось использовать Django REST Framework (DRF), чтобы пострить RESTful API. Я также хочу сбандлить JS ассеты. Сейчас я собираюсь запустить сайт на одном сервере.

Предварительные требования

  • Python 2.x

  • Django 1.9.x

  • npm 2.15.8+

  • Webpack 1.13.x (sudo npm i -g webpack)

  • ESLint 2.13.1+ (sudo npm i -g eslint)

  • NodeJS 4.4.7+

Содержание

  1. Скаффолдинг проекта. Создайте свои начальные директории.

  2. Скаффолдинг проекта на Django.

  3. Настрока переменных среды, нужных для запуска сервера Django.

  4. Установка Django REST Framework и настройка Django с использованием переменных среды.

  5. Создание API.

  6. Запуск Django сервера с использованием dev settings.

  7. Инициализация npm-пакета и установка front-end JS зависимостей.

  8. Создание Angular entry-point и загрузка начальных зависимостей.

  9. Настройка Webpack'а.

  10. Дайте команду Django загрузить приложение.

  11. Создайте шаблон базы приложения Angular.

  12. Напишите компонент home.

  13. Напишите Angular роуты, ведущие к вашему компоненту home и странице 404.

  14. Добавьте директивы ангуляр-маршрутизатора к шаблону входной точки приложения.

  15. Проверьте ваше REST API в приложении Angular.  Шпаргалка.

Итак, начнем!

0. Настройте среду для Python.

mkvirtualenv mysite  

1. Скаффолдинг проекта на Django. Создайте начальные директории.

Мы хотим сфокусироваться на модулярности в ходе разработки. Следовательно, существует множество директорий в конечном итоге использования. Мы хотим, чтобы наше дерево изначально выглядело так:

mysite  
├── backend
│   ├── docs
│   ├── requirements
└── frontend
    ├── app
    │   ├── components
    │   └── shared
    ├── assets
    │   ├── css
    │   ├── img
    │   ├── js
    │   └── libs
    ├── config
    ├── dist
        └── js

 Сделайте следующее:

mkdir mysite && cd mysite  
mkdir -p backend/docs/ backend/requirements/ \  
         frontend/app/shared/ \
         frontend/app/components/ \
         frontend/config \
         frontend/assets/img/ frontend/assets/css/ \
         frontend/assets/js/ frontend/assets/libs/ \
         frontend/dist/js/

 *Примечание: Структура этого проекта была навеяна опытом с несколькими другими проектами. Я считаю эту организацию идеальной, но вам не обязательно ей следовать. Но, пока вы читаете этот гайд, вы должны придерживаться этой структуры.

2. Скаффолдинг проекта на Django.

В директории backend/ создайте Django проект:

python django-admin.py startproject mysite  

 Также создайте requirements.txt:

pip freeze > requirements/requirements.txt 

В директории (вашего проекта) backend/mysite/ произведите скаффолдинг директории, той, где будет жить ваше API:

mkdir -p applications/api/v1/  
touch applications/__init__.py applications/api/__init__.py \  
        applications/api/v1/__init__.py applications/api/v1/routes.py \
        applications/api/v1/serializers.py applications/api/v1/viewsets.py

Теперь создайте структуру директории настроек:

mkdir -p configlord/settings/  
touch configlord/settings/__init__.py \  
        configlord/settings/base.py configlord/settings/dev.py configlord/settings/prod.py \
        configlord/dev.env configlord/prod.en

3. Настройте переменные окружения, которые нужны для запуска сервера Django.

На этом этапе я предпочитаю пользоваться django-environ для работы с переменными окружения. Существует множество способов сделать это, но пакет django-environ чрезвычайно упрощает этот процесс, поэтому я использую его во всех своих проектах.

Установите django-environ:

pip install django-environ 

 В mysite/dev.env добавьте следующее:

DATABASE_URL=sqlite:///mysite.db  
DEBUG=True  
FRONTEND_ROOT=path/to/mysite/frontend/  
SECRET_KEY=_some_secret_key 

Мы собираемся использовать эти переменные среды в наших настройках. Выгода от использования наших переменных окружения в отдельных файлах состоит в основном в том, что такая настройка позволяет облегчить переключение между средами. В нашем случае файл the dev.env является списком переменных, которые мы бы использовали в локальной среде разработки.

*Примечание: SECRET_KEY можно взять из settings.py, который был сгенерирован django-admin.py startproject.

4. Установите Django REST Framework и настройте Django, используя переменные среды.

Установка DRF:

pip install djangorestframework 

Наполните settings/base.py  следующим:

Укажите, где искать переменные окружения.

import environ

project_root = environ.Path(__file__) - 3  
env = environ.Env(DEBUG=(bool, False),)  
CURRENT_ENV = 'dev' # 'dev' is the default environment

# read the .env file associated with the settings that're loaded
env.read_env('./mysite/{}.env'.format(CURRENT_ENV))

Установите базу данных. В данном случае мы собираемся использовать встроенные в django-environ настройки SQLite.

DATABASES = {  
    'default': env.db()
}

Установите SECRET_KEY ,а также debug.

SECRET_KEY = env('SECRET_KEY')  
DEBUG = env('DEBUG')

Добавьте DRF в пул приложений, которые Django должен использовать.

# Application definition
INSTALLED_APPS = [

    ...

    # Django Packages
    'rest_framework',
]

Ссылки будут «жить» в специальном URL модуле, созданном с помощью базы проекта.

ROOT_URLCONF = 'mysite.urls'

Укажите Django, где искать все шаблоны и другие статические ассеты.

STATIC_URL = '/static/'  
STATICFILES_FINDERS = [  
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
STATICFILES_DIRS = [  
    env('FRONTEND_ROOT')
]

TEMPLATES = [  
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [env('FRONTEND_ROOT')],
        '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',
            ],
        },
    },
]

В соответствии с настройкой TEMPLATES Django должен будет искать шаблоны внутри frontend/ directory. Это то, где Angular приложение будет жить. Мы используем только Django, чтобы обслужить шаблон, внутри которого Angular приложение будет загружаться, которое будет выполнено через entry-point директиву. Если вы не знаете, о чем я, продолжайте чтение... 

Наполните settings/dev.py:

from mysite.settings.base import *


CURRENT_ENV = 'dev'

Здесь мы указываем, что этот файл настроек унаследывает настройки из base.py и переопределяет строку CURRENT_ENV, найденную в base.py. Мы говорим: «Используй это значение вместо значения, найденного в наследуемом модуле».

5. Создайте API.

Нам нужно нечто, с помощью чего мы сможем протестировать службы Angular, поэтому давайте создадим небольшое API. Этот шаг можно пропустить, но я не советовал бы делать этого. Нам важно знание того, что настройки приложения Angular работают исключительно с точки зрения его потенциала, чтобы облегчить HTTP запросы.

Сгенерируйте приложение.

manage.py startapp games 

Создайте модель в games/models.py.

class Game(models.model):  
    title = models.CharField(max_length=255)
    description = models.CharField(max_length=750)

Создайте DRF сериализатор для модели игры в  applications/api/v1/serializers.py.

from rest_framework.serializers import ModelSerializer  
from applications.games.models import Game


class GameSerializer(ModelSerializer):

    class Meta:
        model = Game

Создайте  DRF viewset для модели в приложениях applications/api/v1/viewsets.py.

from rest_framework import viewsets  
from applications.games.models import Game  
from applications.api.v1.serializers import GameSerializer


class GameViewSet(viewsets.ModelViewSet):  
    queryset = Game.objects.all()
    serializer_class = GameSerializer

В applications/api/v1/routes.py зарегистрируйте роуты, используя DRF's router registration features.

from rest_framework import routers  
from applications.api.v1.viewsets import GameViewSet


api_router = routers.SimpleRouter()  
api_router.register('games', GameViewSet) 

Обозначьте ссылки для зарегистрированного DRF роута внутри mysite/urls.py:

from django.contrib import admin  
from django.conf.urls import include, url  
from applications.api.v1.routes import api_router

urlpatterns = [  
    url(r'^admin/', admin.site.urls),

    # API:V1
    url(r'^api/v1/', include(api_router.urls)),
]

6. Запустите сервер Django, используя dev settings.

manage.py runserver --DJANGO_SETTINGS_MODULE=mysite.settings.dev 

Впуская DJANGO_SETTINGS_MODULE в runserver, мы «говорим» - работать используя специфические параметры.

Если все работает, у вас появится возможность открыть localhost:8000/api/v1/games и увидеть ответ от DRF. Если все работает – самое время заняться построением приложения Angular. Если нет – направьте автору проблему. Если вы застряли на этом этапе – оставьте комментарий автору под оригиналом публикации.

7. Инициализируйте npm-пакет и установите front-end JS зависимости.

Приложение Angular не будет работать так, как мы хотим, если правильные зависимости не будут установленны. Самое время установить базовые пакеты, которые понадобятся.

Инициализируйте npm-пакет. Прямо из  frontend/ запустите

npm init --yes  

By passing the --yes flag into init, you're telling NPM to generate a package.json using NPM defaults. Otherwise, if you don't pass that in, you'll have to answer questions... Boring.

Установите dev dependencies. 

npm install --save-dev eslint eslint-loader

Установите общие зависимости.

npm install --save eslint eslint-loader angular angular-resource angular-route json-loader mustache-loader lodash

Файл package.json file во frontend/ должен выглядеть приблизительно следующим образом:

{
  "name": "my-app",
  "version": "0.0.1",
  "description": "This is my first angular app.",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "eslint": "^3.1.1",
    "eslint-loader": "^1.4.1"
  },
  "dependencies": {
    "angular": "^1.5.8",
    "angular-resource": "^1.5.8",
    "angular-route": "^1.5.8",
    "eslint": "^3.1.1",
    "eslint-loader": "^1.4.1",
    "json-loader": "^0.5.4",
    "lodash": "^4.13.1",
    "mustache-loader": "^0.3.1"
  }
}

Здесь то, что мы только что установили:

eslint – отличный линтер, благодаря которому код JavaScript будет в порядке (последователен).

eslint-loader – для запуска eslint через Webpack. Чуть позже я объясню концепцию «загрузчиков».

angular -  MVC фреймворк. Если  вы не знали об этом, стоит подумать о том, чтобы закрыть эту страничку прямо сейчас.

angular-resource -  (Angular) HTTP библиотека выбора. Это абстракция $http.

json-loader - загрузчик (снова, используемый Webpack) для распаковки JSON из .json файлов с помощью require() во время работы нашего приложения.

mustache-loader – загрузчик, который мы будем использовать, чтобы парсить наши mustache шаблоны. Mustache шаблоны – это веселье.

Я могу спокойно предположить, что вы не знаете, как все эти пакеты заиграют вместе. 

Не переживайте, братишки.

8. Создайте entry-point в Angular, объявите начальные зависимости, объявите первоначальные глобальные переменные.

В frontend/app/app.js добавьте следующее:

/* Libs */
require("angular/angular");  
require("angular-route/angular-route");  
require("angular-resource/angular-resource");

/* Globals */
_ = require("lodash");  
_urlPrefixes = {  
  API: "api/v1/",
  TEMPLATES: "static/app/"
};

/* Components */

/* App Dependencies */
angular.module("myApp", [  
  "ngResource",
  "ngRoute",
]);

/* Config Vars */
// @TODO in Step 13.

/* App Config */
angular.module("myApp").config(routesConfig);

app.js это то, где Webpack будет искать модули, чтобы бандлить их вместе. Лично я ценю такую организацию и методику вызовов, но такой порядок не обязателен. Существует 6 секций:

  • Libs – главные библиотеки, используемые на протяжении работы Angular приложения;
  • Globals – зарезервированные глобальные переменные, которые мы можем использовать во время работы приложения;
  • Components (Компоненты) – особенные модули проекта;
  • App Dependencies (Зависимости приложения) – объявление входной точки приложения и его зависимостей;
  • Config Vars – переменные, где хранятся настройки, такие как route config;
  • App Config - вводит configs (настройки) в приложение, используя сохраненные из предыдущей секции.

Для того, чтобы globals работали, вам следует указать ESLint на то, какие из переменных - глобальные.

В config/eslint.json добавляем следующее:

{
    "env": {
        "node": true
    },
    "extends": "eslint:recommended",
    "rules": {
        "indent": [
            "error",
            2
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "double"
        ],
        "semi": [
            "error",
            "always"
        ],
        "no-console": 0
    },
    "globals": {
        "_": true,
        "_urlPrefixes": true,
        "angular": true,
        "inject": true,
        "window": true
    },
    "colors": true
}

Ниже несколько переменных, о которых мы предупредили ESLint:

  • _ представить lodash.
  • _urlPrefixes – объект, который мы будем использовать в приложении для гиперссылок. Я расскажу об этом позже.
  • angular, чтобы представить AngularJS object driving our entire application.
  • inject, который будет использоваться для ввода зависимостей Angular.
  • window, которая просто представляет объекты окон в JavaScript, является представителем  DOM.

9. Настройка Webpack.

Теперь, когда мы выложили большинство наших зависимостей приложения, мы можем построить config file для Webpack. Webpack будет консолидировать все зависимости, а также модули для приложений, которые мы создаем в один файл. В bundle.

В frontend/webpack.config.js добавляем следующее.

module.exports = {  
    entry: "./app/app.js",
    output: {
        path: "./dist/js/",
        filename: "bundle.js",
        sourceMapFilename: "bundle.js.map",
    },

    watch: true,

    // eslint config
    eslint: {
      configFile: './config/eslint.json'
    },

    module: {
        preLoaders: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "eslint-loader"
        }],
        loaders: [
          { test: /\.css$/, loader: "style!css" },
          { test: /\.html$/, loader: "mustache-loader" },
          { test: /\.json$/, loader: "json-loader" }]
    },

    resolve: {
        extensions: ['', '.js']
    }
};

Для того, чтобы Webpack бандлил все наши статические зависимости, нам нужно указать ему, где их брать, какие зависимости обрабатывать и как управлять ими до банлинга.

Давайте посмотрим на то, что указывает Webpack с помощью webpack.config.js:

Entry - это путь к тому, что Webpack'у нужно для старта бандлинга. Это можеть быть полный путь или путь, относительный тому, где webpack.config.js располагается. В данном случае мы говорим о последнем варианте.

output -  это объект, содержащий в себе path, который является директорией, в которую связанные зависимости будут помещаться; filename - это название бандла; и, в данном случае, мы решили использовать sourceMapFilename, чтобы обозначить, что наша() source map будет вызван(а).

watch указывает Webpack следить за изменениями в файле, пока он выполняется. Если это не настроено как true, Webpack прогонит процесс бандлинга единожды и остановится.

eslint содержит в себе специфические ESLint настройки, используемые eslint-loader.

module указывает Webpack'у, что делать с модулями, с которыми он работает.

module.preLoaders «говорит», что делать перед бандлингом. В данном случае мы хотим запустить модули (исключив модули установленные npm) через eslint.

module.loaders - это то, где указана последовательность загрузчика. В нашем случае мы просто настраиваем test и loader,  где test указывает Webpack’у, какие модули запускать в загрузчике (по соответствию с паттерном regex), и loader говорит Webpack’y, какой загрузчик использовать в модулях, которые соответствуют regex паттерну в test. Каждый загрузчик указан в строке и разделен восклицательным знаком. Ex:  loader!another_loader!yet_another_loader

module.preLoaders указывает, какие preLoaders'у запускать модули. Используемые настройки такие же точно, какие мы использовали в module.loaders.

Но, Грег, какая  разница между preLoaders и loaders? Я рад, что ты спросил, мой дорогой друг!!

A loader указывает Webpack'у, как бандлить требуемые файлы. Loader смотрит на модуль и говорт: «Эй, так как вы упаковываете это в один файл как строку – это то, как оно должно быть преобразованно для bundle'а».

A preLoader обрабатывает код перед loaders, например, чтобы слинтить JavaScript модули.

A postLoader является плагином Webpack'а, который обрабатывает код после бандинга. Мы не специфицировали ни один  postLoader ради простоты.

10. Укажите Django загрузить приложение.

Прямо сейчас все, что нужно сделать – указать Webpack’у что создавать, как создавать и что должно быть создано. (На данном этапе я бы очень удивился, если вы попробуете запустить его и он заработает без ошибок. Если так и есть, я чертов мужик.)

Так как Django использует свой собственный URL процессор в нашем приложении, мы можем быть рады тому, как любезно Django управляет всем тем, что введено в строку браузера пользователя. Как бы то ни было, мы бандлим одностраничное приложение, используя абсолютно другой фреймворк, и хотим, чтобы у приложения был полный контроль над тем, что пользователь вводит. Все, что нам нужно  – обслуживать одну страничку, в которой работает SPA. Следовательно...

В backend/mysite/mysite/urls.py добавляем в список urlpatterns следующее:

# Web App Entry
url(r'^$', TemplateView.as_view(template_name="app/index.html"), name='index'), 

Это значит, что когда пользователь открывает mysite.com/env('FRONTEND_ROOT') + app/index.html будет находить STATICFILES_FINDERS  в порядке рендера HTML шаблона.

11. Создайте шаблон базы приложения Angular.

frontend/app/components/app/index.html шаблон должен выглядеть как обычный шаблон Django.

В frontend/app/index.html добавляем следующее:

{% load staticfiles %}
  
<html ng-app="myApp">  
  <head>
    <title>My Sitetitle>
    <script src="{% static 'dist/js/bundle.js' %}">script>
  head>
  <body>
  body>
html> 

В таком случае вам удастся запустить Webpack. Если вы запустите Django сервер и откроете localhost:8000,вы увидите пустую страничку. Если нет – дайте знать автору.

12. Напишите home component.

Давайте напишем наш первый компонент. Он отобразит текст на страничке, пока пользователь открывает localhost:8000.

Создайте директорию для компонента и базовые файлы. В frontend/app/components/:

mkdir home && touch home/home-controller.js home/home.js home/home.html

В frontend/app/components/home/home.html добавляем следующее:

<div ng-controller="HomeController as ctrl">  
    <div>
        <h1>Home!h1>
    div>
div> 

Теперь добавим следующее в  frontend/app/components/home/home-controller.js:

function HomeController() {  
  var that = this;
  that.foo = "Foo!";
  console.log(that); // should print out the controller object
}

angular.module("Home")  
  .controller("HomeController", [
    HomeController
  ])

Определение модуля Angular должно быть объявлено в home.js:

angular.module("Home", []);

require("./home-controller");  

Теперь мы можем сослаться на "Home" в области зависимости определения модуля. Давайте сделаем это!

В app/app.js добавьте следующее:

/* Components */
require("./components/home/home");

/* App Dependencies */
angular.module("myApp", [  
  "Home", // this is our component
  "ngResource",
  "ngRoute"
]);

13. Пропишите пути Angular'а, ведущие к home component и страничке 404.

Нам нужно настроить первый путь. Когда пользователь попадает на localhost:8000, Angular должен взять контроль над загрузкой отрендеренного шаблона. Чтобы сделать это, нам потребуется использовать angular-router.

В frontend/app/routes.js пишем следующее:

function routesConfig($routeProvider) {  
  $routeProvider
    .when("/", {
      templateUrl: _urlPrefixes.TEMPLATES + "components/home/home.html",
      label: "Home"
    })
    .otherwise({
      templateUrl: _urlPrefixes.TEMPLATES + "404.html"
    });
}

routesConfig.$inject = ["$routeProvider"];

module.exports = routesConfig; 

Если мы не добавим _urlPrefixes.TEMPLATES, angular-router предположит, что components/home/home.html является действительной ссылкой, которую узнает сервер. Так как STATIC_URL в настройках предполагает неправильную работу localhost:8000/components/home/home.html.

Также, если вы еще не заметили, вы увидите otherwise({...})  в коде роутов. Это то, как будут реализованы страницы 404.

В frontend/app/404.html добавляем следующее:

<h1>NOT FOUNDh1> 

И в завершении  добавляем frontend/app/app.js:

/* Config Vars */
var routesConfig = require("./routes");  

14. Добавьте директивы angular-router к шаблону точки входа приложения.

А теперь нам нужно указать Angular, где будет происходить переключение отображаемого, когда пользователь пользуется навигацией. Чтобы сделать это, мы используем всю силу angular-router.

В тэг  

 в frontend/app/index.html добавляем:

<base href="/">  

Теперь в тэг 

добавляем:

<div ng-view>div>

Ваш index.html теперь должен выглядеть так:

{% load staticfiles %}
  
<html ng-app="myApp">  
  <head>
    <title>My Sitetitle>
      <script src="{% static 'dist/js/bundle.js' %}" >script>
      <base href="/">
  head>
  <body>
    <div>
      <div ng-view>div>
    div>
  body>
html>  

Запустите Webpack. Откройте localhost:8000. Вы должны увидеть, что произошло в home/home.html. (Если ничего, отправьте эти данные автору J ).

15. Проверьте REST API в приложении Angular.

Если все сделано, у вас появится возможность написать angular службы для Django API. Давайте создадим небольшой компонент, чтобы увидеть, можем ли мы это сделать. Этот компонент должен перечислять игры. Я предполагаю, что вы уже заполнили базы данных, следовательно запрос HTTP к localhost:8000/api/v1/games вернет список игр.

Создайте скаффолд компонент в frontend/app/components/:

mkdir -p game/list/ && touch game/list/game-list-controller.js game/list/game-list-controller_test.js game/game-service.js game/game.js game/game.html  

Этот компонент будет перечислять игры.

Этот компонент должен перечислять игры. Я предполагаю, что вы уже заполнили базы данных, следовательно запрос HTTP к localhost:8000/api/v1/games вернет список игр.

В game/game-service.js:

function GameService($resource) {  
  /**
   * @name GameService
   *
   * @description
   * A service providing game data.
   */

  var that = this;

  /**
   * A resource for retrieving game data.
   */
  that.GameResource = $resource(_urlPrefixes.API + "games/:game_id/");

  /**
   * A convenience method for retrieving Game objects.
   * Retrieval is done via a GET request to the ../games/ endpoint.
   * @param {object} params - the query string object used for a GET request to ../games/ endpoint
   * @returns {object} $promise - a promise containing game-related data
   */
  that.getGames = function(params) {
    return that.GameResource.query(params).$promise;
  };
}

angular.module("Game")  
  .service("GameService", ["$resource", GameService]);

Обратите внимание на ссылку $resource, которую мы используем для того, чтобы настроить механизмы HTTP в нашей службе.

В game/list/game-list-controller.js:

function GameListController(GameService) {  
  var that = this;

  /* Stored game objects. */
  that.games = [];

  /**
   * Initialize the game list controller.
   */
  that.init = function() {
    return GameService.getGames().then(function(games) {
      that.games = games;
    });
  };
}

angular.module("Game")  
  .controller("GameListController", [
    "GameService",
    GameListController
  ]);

В game/game.html:

<div ng-controller="GameListController as ctrl" ng-init="ctrl.init()">  
    <div>
        <h1>Gamesh1>
        
        <ul>
          <li ng-repeat="game in ctrl.games">{{ game.title }}li>
        ul>
    div>
div> 

В game/game.js:

angular.module("Game", []);

require("./list/game-list-controller");  
require("./game-service");  

Затем обратимся к компоненту в app.js:

/* Components */
require("./components/game/game");

/* App Dependencies */
angular.module("myApp", [  
  "Home",
  "Game",
  "ngResource",
  "ngRoute"
]);

В конце концов, мы собираемся настроить роуты для списка игр, поэтому в frontend/app/routes.js добавьте следующее в объект $routeProvider:

 .when("/game", {
      templateUrl: _urlPrefixes.TEMPLATES + "components/game/list/game-list.html",
      label: "Games"
    })

Запустите Webpack снова. Все должно верно скомпилироваться. Если нет – дайте знать автору.

Откройте localhost:8000/#/games. Вы увидите список игр.

Сделано!

Это все.

Сомнения/Мысли

Но есть некоторые сомнения:

Глобальные переменные могут конкретно подставить вас, если вы не знаете, как с ними работать. Их локальное поведение не гарантирует того же на продакшене. Насколько я помню, их можно заставить работать, если правильно описан метод. Ваше приложение на Angular тесно связанно с Django. Поэтому ваше приложение не будет просто слиянием back- и фронтенда. Если ваш Django-RIP давно устарел, значит поменялись и маршруты, следовательно сконфигурируете ваш бэкенд согласно тому, как должны вести себя статические файлы. Так же вам будет необходимо заменить index.html с точкой входа Angular. Маленькие проекты не дадут вам особо попотеть, а вот большие явно заставят понервничать. Совет: единственное место, где должны сопрягаться приложение на Angular и Django сервер - это одна точка входа.

Деплоймент должен быть выполнен так же, как любой обычный деплоймент приложения.

Это все. Если у вас есть какие-либо вопросы и вы испытываете трудности, пожалуйста, оставьте их в комментариях в исходной статье!

Чит!

Автор пообещал выложить на гитхабе репозиторий со всем кодом.

Оригинальная статья на английском языке. 

КОММЕНТАРИИ И ОБСУЖДЕНИЯ
advertisement advertisement

Покупай подпискус доступом ко всем курсам и сервисам

Библиотека современных IT знаний в удобном формате

Выбирай свой вариант подписки в зависимости от задач, стоящих перед тобой. Но если нужно пройти полное обучение с нуля до уровня специалиста, то лучше выбирать Базовый или Премиум. А для того чтобы изучить 2-3 новые технологии, или повторить знания, готовясь к собеседованию, подойдет Пакет Стартовый.

Стартовый
  • Все видеокурсы на 3 месяца
  • Тестирование по 10 курсам
  • Проверка 5 домашних заданий
  • Консультация с тренером 30 мин
59.99 $
Оформить подписку
Базовый
  • Все видеокурсы на 6 месяцев
  • Тестирование по 16 курсам
  • Проверка 10 домашних заданий
  • Консультация с тренером 60 мин
89.99 $
Оформить подписку
Премиум
  • Все видеокурсы на 1 год
  • Тестирование по 24 курсам
  • Проверка 20 домашних заданий
  • Консультация с тренером 120 мин
169.99 $
Оформить подписку
Notification success