DjangularJS is a full-stack framework based on Django and AngularJS focused on programmer happiness and sustainable productivity.
It aims to solve the common issues with connecting those frameworks, support daily development needs and help developers to use best practices.
Design goals:
- Separation of concerns
- Convention over configuration
- Modularity
- Automation (as much as possible!)
Getting started
Project structure
DjangularJS comes with guidelines on how to organize your project. For example:
- Django (ie Back-end) stuffs are located in
<project-name>/server
folder - Angular (ie Front-end) stuffs are located in
<project-name>/public
folder - Ansible (ie provisioning) stuffs are located in
<project-name>/provisioning
folder
The global structure is described below:
. (project root)
+-- provisioning/ Ansible configuration (optional but recommended)
|
+-- public/ AngularJS app (front-end)
| +-- _/ contains bower packages (see .bowerrc)
| +-- core/ main module (mandatory)
| +-- i18n/ contains translations for each language (optional)
| +-- angular-module0/
| | +-- constants/ contains angular constants for module0 (optional)
| | +-- controllers/ contains angular controllers for module0 (optional)
| | +-- directives/ contains angular directives for module0 (optional)
| | +-- filters/ contains angular filters for module0 (optional)
| | +-- img/ contains images used in module0 (optional)
| | +-- modals/ contains modal views used in module0 (optional)
| | +-- services/ contains angular services for module0 (optional)
| | +-- styles/ contains Sass' partials for both views and templates (optional)
| | +-- templates/ contains templates (ie partial views) for both directives and modals (optional)
| | +-- tests/ contains module0's tests (optional but recommended)
| | | +-- *.spec.js unit test (karma + jasmine) (optional)
| | | +-- *.e2e.js protractor test (karma + jasmine) (optional)
| | | +-- module0.fake-data.js special file use to provide data on for your unit tests (optional)
| | +-- views/ contains views for module0 (optional)
| | +-- module0.module.js configuration file for module0 (mandatory)
| +-- ...
| +-- config.js global configuration file for the AngularJS app (mandatory)
| +-- config.scss global configuration file and entry point for Sass (mandatory)
|
+-- requirements/ python dependencies for both development and production (mandatory)
|
+-- server/ Django project (back-end) (mandatory)
| +-- core/ main module (mandatory)
| +-- django-module0
| | +-- fixtures/ contains initial/test data for module0 (optional)
| | +-- serializers/ contains module0's serialiazers (python module) (optional)
| | +-- templates/ contains module0's templates (optional)
| | +-- templatetags/ contains templatetags used in module0 (optional)
| | +-- tests/ contains module0's tests (should match test_*.py) (optional but recommended)
| | +-- views/ contains both APIViews and Viewsets (optional)
| | +-- urls.py lists module0's routes (optional)
| +-- ...
| +-- settings/ special folder containing Django settings (mandatory)
| +-- urls.py lists modules and third party routes (mandatory)
|
+-- package.json npm (ie NodeJS) dependencies (mandatory)
+-- bower.json front-end (ie bower) dependencies (mandatory)
+-- assets.json special file used to locate front-end dependencies (mandatory)
+-- gruntfile.js configuration file for Grunt (mandatory)
+-- Vagrantfile configuration file for Vagrant (optional but recommended)
Conventions
-
Instructions are to be run from the root directory of your project
-
Instructions like
@host $ ...
should be executed from the host (ie. from your computer) -
Instructions like
@dev0 $ ...
should be executed fromdev0
(ie. inside vagrant, in the vm hosting your web app)Use
@host $ vagrant ssh dev0
to connect todev0
Development machines are listed in
provisioning/vagrant.yml
-
Instructions like
(vagrant)@dev0 $ ...
expectvirtualenv
to be activated.Use
@dev0 $ cd /vagrant && source bin/activate
to enablevirtualenv
Prerequisites & Dependencies
Make sure you have installed all of the following prerequisites on your development machine:
-
Vagrant - easy way to create and configure lightweight, reproducible, and portable development environments.
-
Ansible - tool to manage your servers
-
bower - front-end dependencies manager
@host $ npm install -g bower
-
grunt, yeoman and generator-djangularjs - automation tools
@host $ npm install -g grunt-cli yo generator-djangularjs
NOTE: Even if Vagrant and Ansible are recommended, you can use DjangularJS without them (it assumes you know what you are doing).
Project Setup
@host $ mkdir <project_name> && cd <project_name>
@host $ yo djangularjs
The generator will ask you a few questions about your new application and will generate it for you.
Warning (for Windows user only): Since Windows does not support nfs you have to disable it in your Vagrantfile
. Replace machine.vm.synced_folder ".", "/vagrant", type: "nfs"
by machine.vm.synced_folder ".", "/vagrant"
Since your have generated the project with the previous command, you should now be able to:
- Setup your development environment
- Install project dependencies
- Apply third party apps migrations
- Run tests to make sure everything is fine
- Build css from Sass
- Generate translations for angular-translate (see grunt-djangularjs-translate for more info)
- Run your server using grunt
Before you start: take a look to provisioning/vagrant.yml
and make sure your machine has enough memory.
# 1. Setup your development environment
@host $ sudo ansible-galaxy install -r provisioning/requirements.yml
@host $ vagrant up # take a while
@host $ vagrant ssh dev0
@dev0 $ cd /vagrant && . bin/activate # activate virtualenv
# 2. Install project dependencies
(vagrant)@dev0 $ npm install # install node/iojs dependencies
(vagrant)@dev0 $ bower install # install front-end dependencies
(vagrant)@dev0 $ pip install -r requirements/dev.txt
# 3. Apply third party apps migrations
(vagrant)@dev0 $ python manage.py migrate
# 4. Run tests to make sure everything is fine
(vagrant)@dev0 $ grunt test
# 5+6. Build css from Sass and translations
(vagrant)@dev0 $ grunt sass translate
# 7. Run your server using grunt
(vagrant)@dev0 $ grunt serve
Your Web application should now be available from your browser (see http://localhost:9000/)
Notes:
- you need to create a superuser to access admin UI (http://localhost:9000/admin)
(vagrant)@dev0 $ python manage.py createsuperuser
See Django doc for more info.
- your development environment comes with 2 machines:
dev0
which hosts your web appdev1
which hosts external services such as databases, brokers, dumps, etc. (using Docker or not)
You can create as many machines as you like (as long as your computer can grant them memory)
See provisioning/vagrant.yml
for more information
Secrets management
DjangularJS store sensitive information such as Django SECRET_KEY
, passwords, etc. in Ansible group variables (see provisioning/group_vars/*
).
To make sure they stay secret, you have to encrypt them using Ansible Vault:
@host $ ansible-vault encrypt provisioning/group_vars/*
Since your Ansible configuration now contains encrypted files, you have to configure vagrant to ask you for the password before trying to provision your development environment.
To do so, edit Vagrantfile
and uncomment the line ansible.ask_vault_pass = "true"
You should now be able to run @host $ vagrant provision
Note:
- Use
@host $ ansible-vault decrypt provisioning/group_vars/*
to decrypt files - Once group variables file are encrypted they can be included into your version control system
- During provisioning, ansible will create a file called
server/settings/.secrets.yml
:- Make sure this file is ignored from your version control system
- Do NOT modify this file directly. If your configuration change then:
- Edit
provisioning/group_vars/...
files - Run provisioning again using
@host $ vagrant provision
- Edit
See following files for more information:
provisioning/roles.yml
provisioning/group_vars/all
provisioning/group_vars/dev
provisioning/roles/web-app-conf
server/settings/.secrets.yml
server/settings/base.py
Quick reference
Grunt tasks
- Run server:
- development mode:
(vagrant)@dev0 $ grunt serve
[1] - production like mode (ie with minified assets):
(vagrant)@dev0 $ grunt serve-production-insecure
- development mode:
- Run tests:
- all:
(vagrant)@dev0 $ grunt test
- front-end only:
grunt jshint karma:unit
- back-end only:
(vagrant)@dev0 $ grunt django-manage:test
[2]
- all:
- Compile stylesheets:
grunt sass
- Check/compile translations:
grunt translate
[1] (vagrant)@dev0 $ python manage.py runserver 0.0.0.0:3000
works too
[2] (vagrant)@dev0 $ python manage.py test --settings=server.settings.tests
works too
Generators
DjangularJS comes with a yeoman generator called generator-djangularjs.
You should definitely use it as much as possible since it will help you to:
- save precious time
- keep your project tested and organized
AngularJS generators
- new module:
yo djangularjs:angular-module <module-name>
- new directive:
yo djangularjs:angular-directive <directive-name>
- new filter:
yo djangularjs:angular-filter <filter-name>
- new service:
yo djangularjs:angular-service <service-name>
- new controller:
yo djangularjs:angular-controller <controller-name>
- new route:
yo djangularjs:angular-route <route-name>
(will also create a controller and a view for this route)
Django generators
- new module (or django app):
yo djangularjs:django-module <module-name>
- new DRF APIView:
yo djangularjs:django-api-view <view-name>
- new DRF ViewSet:
yo djangularjs:django-viewset <viewset-name>
- new DRF Serializer:
yo djangularjs:django-serializer <serializer-name>
- new Django template tag:
yo djangularjs:django-templatetag <templatetag-name>
- new Django filter:
yo djangularjs:django-filter <filter-name>
Stack
Front-end
Component | Description |
---|---|
AngularJS | Superheroic JavaScript MVW Framework |
Bootstrap | Sleek, intuitive, and powerful mobile first front-end framework for faster and easier web development |
angular-translate | Makes your life much easier when it comes to i18n and l10n (internationalization) |
Angular UI | The companion suite(s) to the AngularJS framework |
Sass | Most mature, stable, and powerful professional grade CSS extension language in the world |
Back-end
Component | Description |
---|---|
Django | The Web framework for perfectionists with deadlines |
Django Rest Framework | Powerful and flexible toolkit that makes it easy to build Web APIs |
Django compressor | Compresses linked and inline JavaScript or CSS into a single cached file |
Automation
Component | Description |
---|---|
Grunt | The JavaScript Task Runner |
Yeoman | The web's scaffolding tool for modern webapps |
Karma | Spectacular Test Runner for Javascript |
Bower | A package manager for the web |
Vagrant | Development environments made easy |
Ansible | Simplest way to automate apps and IT infrastructure |
Credits
Inspired from MEANJS
License
The MIT License (MIT)
Copyright (c) 2015-2016 Nicolas Panel
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.