Merge branch 'master' into feature/docker-compose-gulp

# Conflicts:
#	{{cookiecutter.project_slug}}/gulpfile.js
This commit is contained in:
Bruno Alla 2019-03-02 12:02:09 -03:00
commit b0f5fb9b76
29 changed files with 348 additions and 232 deletions

View File

@ -57,7 +57,9 @@ Listed in alphabetical order.
Andrew Mikhnevich `@zcho`_
Andy Rose
Anna Callahan `@jazztpt`_
Anna Sidwell `@takkaria`_
Antonia Blair `@antoniablair`_ @antoniablairart
Anuj Bansal `@ahhda`_
Arcuri Davide `@dadokkio`_
Areski Belaid `@areski`_
Ashley Camba
@ -70,6 +72,7 @@ Listed in alphabetical order.
Bouke Haarsma
Brent Payne `@brentpayne`_ @brentpayne
Burhan Khalid            `@burhan`_                   @burhan
Carl Johnson `@carlmjohnson`_ @carlmjohnson
Catherine Devlin `@catherinedevlin`_
Cédric Gaspoz `@cgaspoz`_
Charlie Smith `@chuckus`_
@ -78,6 +81,7 @@ Listed in alphabetical order.
Chris Franklin `@hairychris`_
Chris Pappalardo `@ChrisPappalardo`_
Christopher Clarke `@chrisdev`_
Cole Mackenzie `@cmackenzie1`_
Collederas `@Collederas`_
Cristian Vargas `@cdvv7788`_
Cullen Rhodes `@c-rhodes`_
@ -85,6 +89,7 @@ Listed in alphabetical order.
Daniel Hepper `@dhepper`_ @danielhepper
Daniele Tricoli `@eriol`_
David Díaz `@ddiazpinto`_ @DavidDiazPinto
Davit Tovmasyan `@davitovmasyan`_
Davur Clementsen `@dsclementsen`_ @davur
Delio Castillo `@jangeador`_ @jangeador
Denis Orehovsky `@apirobot`_
@ -106,6 +111,7 @@ Listed in alphabetical order.
Irfan Ahmad `@erfaan`_ @erfaan
Jan Van Bruggen `@jvanbrug`_
Jens Nilsson `@phiberjenz`_
Jerome Leclanche `@jleclanche`_ @Adys
Jimmy Gitonga `@afrowave`_ @afrowave
John Cass `@jcass77`_ @cass_john
Julien Almarcha `@sladinji`_
@ -119,6 +125,7 @@ Listed in alphabetical order.
Krzysztof Szumny `@noisy`_
Krzysztof Żuraw `@krzysztofzuraw`_
Leonardo Jimenez `@xpostudio4`_
Leo Zhou `@glasslion`_
Lin Xianyi `@iynaix`_
Luis Nell `@originell`_
Lukas Klein
@ -140,6 +147,7 @@ Listed in alphabetical order.
Pablo `@oubiga`_
Parbhat Puri `@parbhat`_
Peter Bittner `@bittner`_
Peter Coles `@mrcoles`_
Pierre Chiquet `@pchiquet`_
Raphael Pierzina `@hackebrot`_
Raony Guimarães Corrêa `@raonyguimaraes`_
@ -162,6 +170,7 @@ Listed in alphabetical order.
Tom Atkins `@knitatoms`_
Tom Offermann
Travis McNeill `@Travistock`_ @tavistock_esq
Tubo Shi `@Tubo`_
Umair Ashraf `@umrashrf`_ @fabumair
Vitaly Babiy
Vivian Guillen `@viviangb`_
@ -169,6 +178,9 @@ Listed in alphabetical order.
William Archinal `@archinal`_
Yaroslav Halchenko
Denis Bobrov `@delneg`_
Philipp Matthies `@canonnervio`_
Vadim Iskuchekov `@Egregors`_ @egregors
Keith Bailey `@keithjeb`_
========================== ============================ ==============
.. _@a7p: https://github.com/a7p
@ -191,6 +203,7 @@ Listed in alphabetical order.
.. _@burhan: https://github.com/burhan
.. _@c-rhodes: https://github.com/c-rhodes
.. _@caffodian: https://github.com/caffodian
.. _@carlmjohnson: https://github.com/carlmjohnson
.. _@catherinedevlin: https://github.com/catherinedevlin
.. _@ccurvey: https://github.com/ccurvey
.. _@cdvv7788: https://github.com/cdvv7788
@ -198,7 +211,9 @@ Listed in alphabetical order.
.. _@chrisdev: https://github.com/chrisdev
.. _@ChrisPappalardo: https://github.com/ChrisPappalardo
.. _@chuckus: https://github.com/chuckus
.. _@cmackenzie1: https://github.com/cmackenzie1
.. _@Collederas: https://github.com/Collederas
.. _@davitovmasyan: https://github.com/davitovmasyan
.. _@ddiazpinto: https://github.com/ddiazpinto
.. _@dezoito: https://github.com/dezoito
.. _@dhepper: https://github.com/dhepper
@ -214,14 +229,16 @@ Listed in alphabetical order.
.. _@garry-cairns: https://github.com/garry-cairns
.. _@garrypolley: https://github.com/garrypolley
.. _@goldhand: https://github.com/goldhand
.. _@glasslion: https://github.com/glasslion
.. _@hackebrot: https://github.com/hackebrot
.. _@hairychris: https://github.com/hairychris
.. _@hendrikschneider https://github.com/hendrikschneider
.. _@hendrikschneider: https://github.com/hendrikschneider
.. _@hjwp: https://github.com/hjwp
.. _@IanLee1521: https://github.com/IanLee1521
.. _@ikkebr: https://github.com/ikkebr
.. _@iynaix: https://github.com/iynaix
.. _@jazztpt: https://github.com/jazztpt
.. _@jleclanche: https://github.com/jleclanche
.. _@juliocc: https://github.com/juliocc
.. _@jvanbrug: https://github.com/jvanbrug
.. _@ka7eh: https://github.com/ka7eh
@ -256,9 +273,11 @@ Listed in alphabetical order.
.. _@ssteinerX: https://github.com/ssteinerx
.. _@stepmr: https://github.com/stepmr
.. _@suledev: https://github.com/suledev
.. _@takkaria: https://github.com/takkaria
.. _@timfreund: https://github.com/timfreund
.. _@Travistock: https://github.com/Tavistock
.. _@trungdong: https://github.com/trungdong
.. _@Tubo: https://github.com/tubo
.. _@viviangb: https://github.com/viviangb
.. _@xpostudio4: https://github.com/xpostudio4
.. _@yunti: https://github.com/yunti
@ -278,6 +297,8 @@ Listed in alphabetical order.
.. _@delneg: https://github.com/delneg
.. _@purplediane: https://github.com/purplediane
.. _@umrashrf: https://github.com/umrashrf
.. _@ahhda: https://github.com/ahhda
.. _@keithjeb: https://github.com/keithjeb
Special Thanks
~~~~~~~~~~~~~~

View File

@ -1,6 +1,6 @@
{
"project_name": "My Awesome Project",
"project_slug": "{{ cookiecutter.project_name.lower()|replace(' ', '_')|replace('-', '_') }}",
"project_slug": "{{ cookiecutter.project_name.lower()|replace(' ', '_')|replace('-', '_')|replace('.', '_')|trim() }}",
"description": "Behold My Awesome Project!",
"author_name": "Daniel Roy Greenfeld",
"domain_name": "example.com",
@ -18,6 +18,7 @@
"use_pycharm": "n",
"use_docker": "n",
"postgresql_version": [
"10.5",
"10.4",
"10.3",
"10.2",

0
docs/_static/.gitkeep vendored Normal file
View File

View File

@ -10,6 +10,8 @@ Run these commands to deploy the project to Heroku:
heroku create --buildpack https://github.com/heroku/heroku-buildpack-python
heroku addons:create heroku-postgresql:hobby-dev
# On Windows use double quotes for the time zone, e.g.
# heroku pg:backups schedule --at "02:00 America/Los_Angeles" DATABASE_URL
heroku pg:backups schedule --at '02:00 America/Los_Angeles' DATABASE_URL
heroku pg:promote DATABASE_URL

View File

@ -59,7 +59,7 @@ SSL (Secure Sockets Layer) is a standard security technology for establishing an
It is always better to deploy a site behind HTTPS and will become crucial as the web services extend to the IoT (Internet of Things). For this reason, we have set up a number of security defaults to help make your website secure:
* If you are not using a subdomain of the domain name set in the project, then remember to put the your staging/production IP address in the ``DJANGO_ALLOWED_HOSTS`` environment variable (see :ref:`settings`) before you deploy your website. Failure to do this will mean you will not have access to your website through the HTTP protocol.
* If you are not using a subdomain of the domain name set in the project, then remember to put your staging/production IP address in the ``DJANGO_ALLOWED_HOSTS`` environment variable (see :ref:`settings`) before you deploy your website. Failure to do this will mean you will not have access to your website through the HTTP protocol.
* Access to the Django admin is set up by default to require HTTPS in production or once *live*.

View File

@ -171,6 +171,16 @@ When developing locally you can go with MailHog_ for email testing provided ``us
.. _Mailhog: https://github.com/mailhog/MailHog/
.. _`CeleryTasks`:
Celery tasks in local development
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When not using docker Celery tasks are set to run in Eager mode, so that a full stack is not needed. When using docker the task
scheduler will be used by default.
If you need tasks to be executed on the main thread during development set CELERY_TASK_ALWAYS_EAGER = True in config/settings/local.py.
Possible uses could be for testing, or ease of profiling with DJDT.
.. _`CeleryFlower`:

View File

@ -9,23 +9,54 @@ Setting Up Development Environment
Make sure to have the following on your host:
* virtualenv_;
* pip;
* PostgreSQL.
* Python 3.6
* PostgreSQL_.
* Redis_, if using Celery
First things first.
#. `Create a virtualenv`_.
#. Create a virtualenv: ::
#. Activate the virtualenv you have just created.
$ python3.6 -m venv <virtual env path>
#. Activate the virtualenv you have just created: ::
$ source <virtual env path>/bin/activate
#. Install development requirements: ::
$ pip install -r requirements/local.txt
#. Create a new PostgreSQL database (note: if this is the first time a database is created on your machine you might need to alter a localhost-related entry in your ``pg_hba.conf`` so as to utilize ``trust`` policy): ::
#. Create a new PostgreSQL database using createdb_: ::
$ createdb <what you've entered as the project_slug at setup stage>
$ createdb <what you have entered as the project_slug at setup stage> -U postgres --password <password>
.. note::
if this is the first time a database is created on your machine you might need an
`initial PostgreSQL set up`_ to allow local connections & set a password for
the ``postgres`` user. The `postgres documentation`_ explains the syntax of the config file
that you need to change.
#. Set the environment variables for your database(s): ::
$ export DATABASE_URL=postgres://postgres:<password>@127.0.0.1:5432/<DB name given to createdb>
# Optional: set broker URL if using Celery
$ export CELERY_BROKER_URL=redis://localhost:6379/0
.. note::
Check out the :ref:`settings` page for a comprehensive list of the environments variables.
.. seealso::
To help setting up your environment variables, you have a few options:
* create an ``.env`` file in the root of your project and define all the variables you need in it.
Then you just need to have ``DJANGO_READ_DOT_ENV_FILE=True`` in your machine and all the variables
will be read.
* Use a local environment manager like `direnv`_
#. Apply migrations: ::
@ -35,8 +66,12 @@ First things first.
$ python manage.py runserver 0.0.0.0:8000
.. _virtualenv: http://docs.python-guide.org/en/latest/dev/virtualenvs/
.. _`Create a virtualenv`: https://virtualenv.pypa.io/en/stable/userguide/
.. _PostgreSQL: https://www.postgresql.org/download/
.. _Redis: https://redis.io/download
.. _createdb: https://www.postgresql.org/docs/current/static/app-createdb.html
.. _initial PostgreSQL set up: http://suite.opengeo.org/docs/latest/dataadmin/pgGettingStarted/firstconnect.html
.. _postgres documentation: https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html
.. _direnv: https://direnv.net/
Setup Email Backend
@ -69,9 +104,7 @@ For instance, one of the packages we depend upon, ``django-allauth`` sends verif
Now you have your own mail server running locally, ready to receive whatever you send it.
.. _`Download the latest MailHog release`: https://github.com/mailhog/MailHog/releases
.. _`properly configured`: https://docs.djangoproject.com/en/dev/topics/email/#smtp-backend
.. _`Download the latest MailHog release`: https://github.com/mailhog/MailHog
Console
~~~~~~~
@ -85,14 +118,21 @@ In production, we have Mailgun_ configured to have your back!
.. _Mailgun: https://www.mailgun.com/
Celery
------
If the project is configured to use Celery as a task scheduler then by default tasks are set to run on the main thread
when developing locally. If you have the appropriate setup on your local machine then set
CELERY_TASK_ALWAYS_EAGER = False
in /config/settings/local.py
Sass Compilation & Live Reloading
---------------------------------
If youd like to take advantage of live reloading and Sass compilation you can do so with a little bit of preparation_.
.. _preparation: https://cookiecutter-django.readthedocs.io/en/latest/live-reloading-and-sass-compilation.html
If youd like to take advantage of live reloading and Sass compilation you can do so with a little
bit of preparation, see :ref:`sass-compilation-live-reload`.
Summary
-------

View File

@ -17,7 +17,7 @@ Contents:
developing-locally-docker
settings
linters
live-reloading-and-sass-compilation
testing
deployment-on-pythonanywhere
deployment-on-heroku
deployment-with-docker

View File

@ -1,17 +0,0 @@
PostgreSQL Installation Basics
==============================
.. index:: pip, virtualenv, PostgreSQL
The steps below will get you up and running with PostgreSQL. This assumes you have pip and virtualenv_ installed.
.. _virtualenv: http://docs.python-guide.org/en/latest/dev/virtualenvs/
On Mac
Install PostgreSQLapp_ from the browser and move PostGresSQL into your applications folder. Then install PostgreSQL from HomeBrew_.
$ brew install postgres
.. _PostgreSQLapp: http://postgresapp.com/
.. _HomeBrew: http://brew.sh/

View File

@ -5,9 +5,9 @@ Linters
flake8
-------
------
To run flake8:
To run flake8: ::
$ flake8
@ -19,7 +19,7 @@ The config for flake8 is located in setup.cfg. It specifies:
pylint
------
This is included in flake8's checks, but you can also run it separately to see a more detailed report:
This is included in flake8's checks, but you can also run it separately to see a more detailed report: ::
$ pylint <python files that you wish to lint>
@ -31,9 +31,9 @@ The config for pylint is located in .pylintrc. It specifies:
* max-parents=13
pycodestyle
-----
-----------
This is included in flake8's checks, but you can also run it separately to see a more detailed report:
This is included in flake8's checks, but you can also run it separately to see a more detailed report: ::
$ pycodestyle <python files that you wish to lint>

View File

@ -1,3 +1,5 @@
.. _sass-compilation-live-reload:
Sass Compilation & Live Reloading
=================================

View File

@ -1,7 +1,7 @@
.. _settings:
Settings
==========
========
This project relies extensively on environment settings which **will not work with Apache/mod_wsgi setups**. It has been deployed successfully with both Gunicorn/Nginx and even uWSGI/Nginx.
@ -18,11 +18,10 @@ DJANGO_READ_DOT_ENV_FILE READ_DOT_ENV_FILE False
======================================= =========================== ============================================== ======================================================================
Environment Variable Django Setting Development Default Production Default
======================================= =========================== ============================================== ======================================================================
DATABASE_URL DATABASES auto w/ Docker; postgres://project_slug w/o raises error
DJANGO_ADMIN_URL n/a 'admin/' raises error
DJANGO_CACHES CACHES (default) locmem redis
DJANGO_DATABASES DATABASES (default) See code See code
DJANGO_DEBUG DEBUG True False
DJANGO_SECRET_KEY SECRET_KEY !!!SET DJANGO_SECRET_KEY!!! raises error
DJANGO_SECRET_KEY SECRET_KEY auto-generated raises error
DJANGO_SECURE_BROWSER_XSS_FILTER SECURE_BROWSER_XSS_FILTER n/a True
DJANGO_SECURE_SSL_REDIRECT SECURE_SSL_REDIRECT n/a True
DJANGO_SECURE_CONTENT_TYPE_NOSNIFF SECURE_CONTENT_TYPE_NOSNIFF n/a True
@ -41,6 +40,7 @@ The following table lists settings and their defaults for third-party applicatio
======================================= =========================== ============================================== ======================================================================
Environment Variable Django Setting Development Default Production Default
======================================= =========================== ============================================== ======================================================================
CELERY_BROKER_URL CELERY_BROKER_URL auto w/ Docker; raises error w/o raises error
DJANGO_AWS_ACCESS_KEY_ID AWS_ACCESS_KEY_ID n/a raises error
DJANGO_AWS_SECRET_ACCESS_KEY AWS_SECRET_ACCESS_KEY n/a raises error
DJANGO_AWS_STORAGE_BUCKET_NAME AWS_STORAGE_BUCKET_NAME n/a raises error
@ -49,8 +49,6 @@ DJANGO_SENTRY_CLIENT SENTRY_CLIENT n/a
DJANGO_SENTRY_LOG_LEVEL SENTRY_LOG_LEVEL n/a logging.INFO
MAILGUN_API_KEY MAILGUN_ACCESS_KEY n/a raises error
MAILGUN_DOMAIN MAILGUN_SENDER_DOMAIN n/a raises error
NEW_RELIC_APP_NAME NEW_RELIC_APP_NAME n/a raises error
NEW_RELIC_LICENSE_KEY NEW_RELIC_LICENSE_KEY n/a raises error
======================================= =========================== ============================================== ======================================================================
--------------------------

56
docs/testing.rst Normal file
View File

@ -0,0 +1,56 @@
.. _testing:
Testing
========
We encourage users to build application tests. As best practice, this should be done immediately after documentation of the application being built, before starting on any coding.
Pytest
------
This project uses the Pytest_, a framework for easily building simple and scalable tests.
After you have set up to `develop locally`_, run the following commands to make sure the testing environment is ready: ::
$ pytest
You will get a readout of the `users` app that has already been set up with tests. If you do not want to run the `pytest` on the entire project, you can target a particular app by typing in its location: ::
$ pytest <path-to-app-in-project/app>
If you set up your project to `develop locally with docker`_, run the following command: ::
$ docker-compose -f local.yml run django pytest
Targetting particular apps for testing in ``docker`` follows a similar pattern as previously shown above.
Coverage
--------
You should build your tests to provide the highest level of **code coverage**. You can run the ``pytest`` with code ``coverage`` by typing in the following command: ::
$ docker-compose -f local.yml run django coverage run -m pytest
Once the tests are complete, in order to see the code coverage, run the following command: ::
$ docker-compose -f local.yml run django coverage report
.. note::
At the root of the project folder, you will find the `pytest.ini` file. You can use this to customize_ the ``pytest`` to your liking.
There is also the `.coveragerc`. This is the configuration file for the ``coverage`` tool. You can find out more about `configuring`_ ``coverage``.
.. seealso::
For unit tests, run: ::
$ python manage.py test
Since this is a fresh install, and there are no tests built using the Python `unittest`_ library yet, you should get feedback that says there were no tests carried out.
.. _Pytest: https://docs.pytest.org/en/latest/example/simple.html
.. _develop locally: ../developing-locally.rst
.. _develop locally with docker: ..../developing-locally-docker.rst
.. _customize: https://docs.pytest.org/en/latest/customize.html
.. _unittest: https://docs.python.org/3/library/unittest.html#module-unittest
.. _configuring: https://coverage.readthedocs.io/en/v4.5.x/config.html

View File

@ -9,4 +9,7 @@ This page contains some advice about errors and problems commonly encountered du
#. Internal server error on user registration: make sure you have configured the mail backend (e.g. Mailgun) by adding the API key and sender domain
#. New apps not getting created in project root: This is the expected behavior, because cookiecutter-django does not change the way that django startapp works, you'll have to fix this manually (see `#1725`_)
.. _#528: https://github.com/pydanny/cookiecutter-django/issues/528#issuecomment-212650373
.. _#1725: https://github.com/pydanny/cookiecutter-django/issues/1725#issuecomment-407493176

View File

@ -71,6 +71,9 @@ def remove_utility_files():
def remove_heroku_files():
file_names = ["Procfile", "runtime.txt", "requirements.txt"]
for file_name in file_names:
if file_name == "requirements.txt" and "{{ cookiecutter.use_travisci }}".lower() == "y":
# don't remove the file if we are using travisci but not using heroku
continue
os.remove(file_name)
@ -118,9 +121,11 @@ def generate_random_string(
if using_ascii_letters:
symbols += string.ascii_letters
if using_punctuation:
symbols += string.punctuation.replace('"', "").replace("'", "").replace(
"\\", ""
)
all_punctuation = set(string.punctuation)
# These symbols can cause issues in environment variables
unsuitable = {"'", '"', "\\", "$"}
suitable = all_punctuation.difference(unsuitable)
symbols += "".join(suitable)
return "".join([random.choice(symbols) for _ in range(length)])

View File

@ -4,10 +4,10 @@ binaryornot==0.4.4
# Code quality
# ------------------------------------------------------------------------------
flake8==3.5.0
flake8==3.7.6
# Testing
# ------------------------------------------------------------------------------
tox==3.2.1
pytest==3.8.0
tox==3.6.1
pytest==4.3.0
pytest-cookies==0.3.0

View File

@ -1,6 +1,7 @@
# General
# ------------------------------------------------------------------------------
USE_DOCKER=yes
IPYTHONDIR=/app/.ipython
# Redis
# ------------------------------------------------------------------------------

View File

@ -333,6 +333,7 @@ tags
[Ss]cripts
pyvenv.cfg
pip-selfcheck.json
.env
{% endif %}
### Project template
@ -342,3 +343,7 @@ MailHog
{{ cookiecutter.project_slug }}/media/
.pytest_cache/
{% if cookiecutter.use_docker == 'y' %}
.ipython/
{%- endif %}

View File

@ -7,6 +7,7 @@ www.{% raw %}{$DOMAIN_NAME}{% endraw %} {
header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-Proto {scheme}
header_upstream X-CSRFToken {~csrftoken}
}
log stdout
errors stdout

View File

@ -209,6 +209,17 @@ FIXTURE_DIRS = (
str(APPS_DIR.path('fixtures')),
)
# SECURITY
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-httponly
SESSION_COOKIE_HTTPONLY = True
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-httponly
CSRF_COOKIE_HTTPONLY = True
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-browser-xss-filter
SECURE_BROWSER_XSS_FILTER = True
# https://docs.djangoproject.com/en/dev/ref/settings/#x-frame-options
X_FRAME_OPTIONS = 'DENY'
# EMAIL
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend

View File

@ -79,8 +79,10 @@ INSTALLED_APPS += ['django_extensions'] # noqa F405
# Celery
# ------------------------------------------------------------------------------
{% if cookiecutter.use_docker == 'n' -%}
# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-always-eager
CELERY_TASK_ALWAYS_EAGER = True
{%- endif %}
# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-eager-propagates
CELERY_TASK_EAGER_PROPAGATES = True

View File

@ -41,12 +41,8 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = env.bool('DJANGO_SECURE_SSL_REDIRECT', default=True)
# https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-secure
SESSION_COOKIE_SECURE = True
# https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-httponly
SESSION_COOKIE_HTTPONLY = True
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-secure
CSRF_COOKIE_SECURE = True
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-httponly
CSRF_COOKIE_HTTPONLY = True
# https://docs.djangoproject.com/en/dev/topics/security/#ssl-https
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-seconds
# TODO: set this to 60 seconds first and then to 518400 once you prove the former works
@ -57,10 +53,6 @@ SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool('DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS
SECURE_HSTS_PRELOAD = env.bool('DJANGO_SECURE_HSTS_PRELOAD', default=True)
# https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff
SECURE_CONTENT_TYPE_NOSNIFF = env.bool('DJANGO_SECURE_CONTENT_TYPE_NOSNIFF', default=True)
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-browser-xss-filter
SECURE_BROWSER_XSS_FILTER = True
# https://docs.djangoproject.com/en/dev/ref/settings/#x-frame-options
X_FRAME_OPTIONS = 'DENY'
# STORAGES
# ------------------------------------------------------------------------------

View File

@ -1,173 +1,159 @@
////////////////////////////////
// Setup
////////////////////////////////
////////////////////////////////
//Setup//
////////////////////////////////
// Gulp and package
const { src, dest, parallel, series, watch } = require('gulp')
const pjson = require('./package.json')
// Plugins
var gulp = require('gulp'),
pjson = require('./package.json'),
gutil = require('gulp-util'),
sass = require('gulp-sass'),
autoprefixer = require('gulp-autoprefixer'),
cssnano = require('gulp-cssnano'),
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
concat = require('gulp-concat'),
{% endif %}
rename = require('gulp-rename'),
del = require('del'),
plumber = require('gulp-plumber'),
pixrem = require('gulp-pixrem'),
uglify = require('gulp-uglify'),
imagemin = require('gulp-imagemin'),
spawn = require('child_process').spawn,
runSequence = require('run-sequence'),
browserSync = require('browser-sync').create(),
reload = browserSync.reload;
const autoprefixer = require('autoprefixer')
const browserSync = require('browser-sync').create()
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
const concat = require('gulp-concat')
{% endif %}
const cssnano = require ('cssnano')
const imagemin = require('gulp-imagemin')
const pixrem = require('pixrem')
const plumber = require('gulp-plumber')
const postcss = require('gulp-postcss')
const reload = browserSync.reload
const rename = require('gulp-rename')
const sass = require('gulp-sass')
const spawn = require('child_process').spawn
const uglify = require('gulp-uglify-es').default
// Relative paths function
var pathsConfig = function (appName) {
this.app = "./" + (appName || pjson.name);
var vendorsRoot = 'node_modules/';
function pathsConfig(appName) {
this.app = `./${pjson.name}`
const vendorsRoot = 'node_modules'
return {
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
bootstrapSass: vendorsRoot + '/bootstrap/scss',
bootstrapSass: `${vendorsRoot}/bootstrap/scss`,
vendorsJs: [
vendorsRoot + 'jquery/dist/jquery.slim.js',
vendorsRoot + 'popper.js/dist/umd/popper.js',
vendorsRoot + 'bootstrap/dist/js/bootstrap.js'
`${vendorsRoot}/jquery/dist/jquery.slim.js`,
`${vendorsRoot}/popper.js/dist/umd/popper.js`,
`${vendorsRoot}/bootstrap/dist/js/bootstrap.js`,
],
{% endif %}
app: this.app,
templates: this.app + '/templates',
css: this.app + '/static/css',
sass: this.app + '/static/sass',
fonts: this.app + '/static/fonts',
images: this.app + '/static/images',
js: this.app + '/static/js'
templates: `${this.app}/templates`,
css: `${this.app}/static/css`,
sass: `${this.app}/static/sass`,
fonts: `${this.app}/static/fonts`,
images: `${this.app}/static/images`,
js: `${this.app}/static/js`,
}
};
}
var paths = pathsConfig();
var paths = pathsConfig()
////////////////////////////////
//Tasks//
// Tasks
////////////////////////////////
// Styles autoprefixing and minification
gulp.task('styles', function() {
return gulp.src(paths.sass + '/project.scss')
function styles() {
var processCss = [
autoprefixer(), // adds vendor prefixes
pixrem(), // add fallbacks for rem units
]
var minifyCss = [
cssnano({ preset: 'default' }) // minify result
]
return src(`${paths.sass}/project.scss`)
.pipe(sass({
includePaths: [
{%- if cookiecutter.custom_bootstrap_compilation == 'y' %}
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
paths.bootstrapSass,
{%- endif %}
{% endif %}
paths.sass
]
}).on('error', sass.logError))
.pipe(plumber()) // Checks for errors
.pipe(autoprefixer({browsers: ['last 2 versions']})) // Adds vendor prefixes
.pipe(pixrem()) // add fallbacks for rem units
.pipe(gulp.dest(paths.css))
.pipe(postcss(processCss))
.pipe(dest(paths.css))
.pipe(rename({ suffix: '.min' }))
.pipe(cssnano()) // Minifies the result
.pipe(gulp.dest(paths.css));
});
.pipe(postcss(minifyCss)) // Minifies the result
.pipe(dest(paths.css))
}
// Javascript minification
gulp.task('scripts', function() {
return gulp.src(paths.js + '/project.js')
function scripts() {
return src(`${paths.js}/project.js`)
.pipe(plumber()) // Checks for errors
.pipe(uglify()) // Minifies the js
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest(paths.js));
});
.pipe(dest(paths.js))
}
{%- if cookiecutter.custom_bootstrap_compilation == 'y' %}
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
// Vendor Javascript minification
gulp.task('vendor-scripts', function() {
return gulp.src(paths.vendorsJs)
function vendorScripts() {
return src(paths.vendorsJs)
.pipe(concat('vendors.js'))
.pipe(gulp.dest(paths.js))
.pipe(dest(paths.js))
.pipe(plumber()) // Checks for errors
.pipe(uglify()) // Minifies the js
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest(paths.js));
});
{%- endif %}
.pipe(dest(paths.js))
}
{% endif %}
// Image compression
gulp.task('imgCompression', function(){
return gulp.src(paths.images + '/*')
function imgCompression() {
return src(`${paths.images}/*`)
.pipe(imagemin()) // Compresses PNG, JPEG, GIF and SVG images
.pipe(gulp.dest(paths.images))
});
.pipe(dest(paths.images))
}
{%- if cookiecutter.use_docker == 'n' %}
// Run django server
gulp.task('runServer', function(cb) {
var cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'});
function runServer(cb) {
var cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'})
cmd.on('close', function(code) {
console.log('runServer exited with code ' + code);
cb(code);
});
});
{%- endif %}
console.log('runServer exited with code ' + code)
cb(code)
})
}
// Browser sync server for live reload
gulp.task('browserSync', function() {
function initBrowserSync() {
browserSync.init(
[paths.css + "/*.css", paths.js + "*.js", paths.templates + '*.html'], {
{%- if cookiecutter.use_docker == 'n' %}
proxy: "localhost:8000"
{% else %}
proxy: "django:8000",
open: false
{%- endif %}
});
});
[
`${paths.css}/*.css`,
`${paths.js}/*.js`,
`${paths.templates}/*.html`
], {
proxy: "localhost:8000"
}
)
}
// Watch
gulp.task('watch', function() {
gulp.watch(paths.sass + '/*.scss', ['styles']);
gulp.watch(paths.js + '/*.js', ['scripts']).on("change", reload);
gulp.watch(paths.images + '/*', ['imgCompression']);
gulp.watch(paths.templates + '/**/*.html').on("change", reload);
function watchPaths() {
watch(`${paths.sass}/*.scss`, styles)
watch(`${paths.templates}/**/*.html`).on("change", reload)
watch([`${paths.js}/*.js`, `!${paths.js}/*.min.js`], scripts).on("change", reload)
}
});
// Generate all assets
const generateAssets = parallel(
styles,
scripts,
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}vendorScripts,{% endif %}
imgCompression
)
// Build task
gulp.task('build',
[
'styles',
'scripts',
{%- if cookiecutter.custom_bootstrap_compilation == 'y' %}
'vendor-scripts',
{%- endif %}
'imgCompression'
],
function () {
console.log('Build complete!')
});
// Set up dev environment
const dev = parallel(
runServer,
initBrowserSync,
watchPaths
)
// Default task
gulp.task('default', function() {
runSequence(
[
'styles',
'scripts',
{%- if cookiecutter.custom_bootstrap_compilation == 'y' %}
'vendor-scripts',
{%- endif %}
'imgCompression'
],
[
{%- if cookiecutter.use_docker == 'n' %}
'runServer',
{%- endif %}
'browserSync',
'watch'
]
);
});
exports.default = series(generateAssets, dev)
exports["generate-assets"] = generateAssets
exports["dev"] = dev

View File

@ -6,32 +6,29 @@
{% if cookiecutter.js_task_runner == 'Gulp' -%}
{% if cookiecutter.custom_bootstrap_compilation == 'y' -%}
"bootstrap": "4.1.1",
{% endif -%}
"browser-sync": "^2.14.0",
"del": "^2.2.2",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^5.0.0",
{% if cookiecutter.custom_bootstrap_compilation == 'y' -%}
"gulp-concat": "^2.6.1",
{% endif -%}
"gulp-cssnano": "^2.1.2",
"gulp-imagemin": "^4.1.0",
"gulp-pixrem": "^1.0.0",
"gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "^3.1.0",
"gulp-uglify": "^3.0.0",
"gulp-util": "^3.0.7",
{% if cookiecutter.custom_bootstrap_compilation == 'y' -%}
"jquery": "3.3.1",
"popper.js": "1.14.3",
{% endif -%}
"run-sequence": "^2.1.1"
"autoprefixer": "^9.4.7",
"browser-sync": "^2.14.0",
"cssnano": "^4.1.10",
"gulp": "^4.0.0",
"gulp-imagemin": "^5.0.3",
"gulp-plumber": "^1.2.1",
"gulp-postcss": "^8.0.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "^4.0.2",
"gulp-uglify-es": "^1.0.4",
"pixrem": "^5.0.0"
{%- endif %}
},
"engines": {
"node": ">=0.8.0"
"node": ">=8"
},
"browserslist": [
"last 2 versions"
],
"scripts": {
{% if cookiecutter.js_task_runner == 'Gulp' -%}
"dev": "gulp",

View File

@ -1,16 +1,16 @@
pytz==2018.5 # https://github.com/stub42/pytz
python-slugify==1.2.6 # https://github.com/un33k/python-slugify
Pillow==5.2.0 # https://github.com/python-pillow/Pillow
pytz==2018.9 # https://github.com/stub42/pytz
python-slugify==2.0.1 # https://github.com/un33k/python-slugify
Pillow==5.4.1 # https://github.com/python-pillow/Pillow
{%- if cookiecutter.use_compressor == "y" %}
rcssmin==1.0.6{% if cookiecutter.windows == 'y' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin
{%- endif %}
argon2-cffi==18.3.0 # https://github.com/hynek/argon2_cffi
argon2-cffi==19.1.0 # https://github.com/hynek/argon2_cffi
{%- if cookiecutter.use_whitenoise == 'y' %}
whitenoise==4.1 # https://github.com/evansd/whitenoise
whitenoise==4.1.2 # https://github.com/evansd/whitenoise
{%- endif %}
redis>=2.10.5 # https://github.com/antirez/redis
redis>=2.10.6, < 3 # pyup: < 3 # https://github.com/antirez/redis
{%- if cookiecutter.use_celery == "y" %}
celery==4.2.1 # pyup: <5.0 # https://github.com/celery/celery
celery==4.2.1 # pyup: < 5.0 # https://github.com/celery/celery
{%- if cookiecutter.use_docker == 'y' %}
flower==0.9.2 # https://github.com/mher/flower
{%- endif %}
@ -18,16 +18,16 @@ flower==0.9.2 # https://github.com/mher/flower
# Django
# ------------------------------------------------------------------------------
django==2.0.8 # pyup: < 2.1 # https://www.djangoproject.com/
django==2.0.13 # pyup: < 2.1 # https://www.djangoproject.com/
django-environ==0.4.5 # https://github.com/joke2k/django-environ
django-model-utils==3.1.2 # https://github.com/jazzband/django-model-utils
django-allauth==0.37.1 # https://github.com/pennersr/django-allauth
django-allauth==0.38.0 # https://github.com/pennersr/django-allauth
django-crispy-forms==1.7.2 # https://github.com/django-crispy-forms/django-crispy-forms
{%- if cookiecutter.use_compressor == "y" %}
django-compressor==2.2 # https://github.com/django-compressor/django-compressor
{%- endif %}
django-redis==4.9.0 # https://github.com/niwinz/django-redis
django-redis==4.10.0 # https://github.com/niwinz/django-redis
# Django REST Framework
djangorestframework==3.8.2 # https://github.com/encode/django-rest-framework
djangorestframework==3.9.1 # https://github.com/encode/django-rest-framework
coreapi==2.3.3 # https://github.com/core-api/python-client

View File

@ -2,29 +2,29 @@
Werkzeug==0.14.1 # https://github.com/pallets/werkzeug
ipdb==0.11 # https://github.com/gotcha/ipdb
Sphinx==1.8.0 # https://github.com/sphinx-doc/sphinx
Sphinx==1.8.4 # https://github.com/sphinx-doc/sphinx
{%- if cookiecutter.use_docker == 'y' %}
psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
{%- else %}
psycopg2-binary==2.7.5 # https://github.com/psycopg/psycopg2
psycopg2-binary==2.7.7 # https://github.com/psycopg/psycopg2
{%- endif %}
# Testing
# ------------------------------------------------------------------------------
mypy==0.620 # https://github.com/python/mypy
pytest==3.8.0 # https://github.com/pytest-dev/pytest
pytest-sugar==0.9.1 # https://github.com/Frozenball/pytest-sugar
mypy==0.670 # https://github.com/python/mypy
pytest==4.2.0 # https://github.com/pytest-dev/pytest
pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar
# Code quality
# ------------------------------------------------------------------------------
flake8==3.5.0 # https://github.com/PyCQA/flake8
coverage==4.5.1 # https://github.com/nedbat/coveragepy
flake8==3.7.5 # https://github.com/PyCQA/flake8
coverage==4.5.2 # https://github.com/nedbat/coveragepy
# Django
# ------------------------------------------------------------------------------
factory-boy==2.11.1 # https://github.com/FactoryBoy/factory_boy
django-debug-toolbar==1.10.1 # https://github.com/jazzband/django-debug-toolbar
django-extensions==2.1.2 # https://github.com/django-extensions/django-extensions
django-debug-toolbar==1.11 # https://github.com/jazzband/django-debug-toolbar
django-extensions==2.1.5 # https://github.com/django-extensions/django-extensions
django-coverage-plugin==1.6.0 # https://github.com/nedbat/django_coverage_plugin
pytest-django==3.4.3 # https://github.com/pytest-dev/pytest-django
pytest-django==3.4.7 # https://github.com/pytest-dev/pytest-django

View File

@ -2,16 +2,16 @@
-r ./base.txt
gunicorn==19.8.1 # https://github.com/benoitc/gunicorn
gunicorn==19.9.0 # https://github.com/benoitc/gunicorn
psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
{%- if cookiecutter.use_whitenoise == 'n' %}
Collectfast==0.6.2 # https://github.com/antonagestam/collectfast
{%- endif %}
{%- if cookiecutter.use_sentry == "y" %}
raven==6.9.0 # https://github.com/getsentry/raven-python
raven==6.10.0 # https://github.com/getsentry/raven-python
{%- endif %}
# Django
# ------------------------------------------------------------------------------
django-storages[boto3]==1.7.1 # https://github.com/jschneier/django-storages
django-anymail[mailgun]==4.2 # https://github.com/anymail/django-anymail
django-anymail[mailgun]==5.0 # https://github.com/anymail/django-anymail

View File

@ -11,6 +11,11 @@ if not settings.configured:
app = Celery('{{cookiecutter.project_slug}}')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')
class CeleryAppConfig(AppConfig):
@ -18,11 +23,6 @@ class CeleryAppConfig(AppConfig):
verbose_name = 'Celery Config'
def ready(self):
# Using a string here means the worker will not have to
# pickle the object when using Windows.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')
installed_apps = [app_config.name for app_config in apps.get_app_configs()]
app.autodiscover_tasks(lambda: installed_apps, force=True)

View File

@ -36,7 +36,7 @@
<body>
<div class="m-b-1">
<div class="mb-1">
<nav class="navbar navbar-expand-md navbar-light bg-light">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>