From 3a17f9bc271a7fff90c3dccbef86cd839975cf7d Mon Sep 17 00:00:00 2001 From: "Nikita P. Shupeyko" Date: Fri, 25 May 2018 12:16:04 +0300 Subject: [PATCH 001/126] Remove project doc files likely to remain unused --- {{cookiecutter.project_slug}}/docs/deploy.rst | 4 - .../docs/docker_ec2.rst | 186 ------------------ {{cookiecutter.project_slug}}/docs/index.rst | 14 +- .../docs/install.rst | 4 - 4 files changed, 4 insertions(+), 204 deletions(-) delete mode 100644 {{cookiecutter.project_slug}}/docs/deploy.rst delete mode 100644 {{cookiecutter.project_slug}}/docs/docker_ec2.rst delete mode 100644 {{cookiecutter.project_slug}}/docs/install.rst diff --git a/{{cookiecutter.project_slug}}/docs/deploy.rst b/{{cookiecutter.project_slug}}/docs/deploy.rst deleted file mode 100644 index 1e642c79..00000000 --- a/{{cookiecutter.project_slug}}/docs/deploy.rst +++ /dev/null @@ -1,4 +0,0 @@ -Deploy -======== - -This is where you describe how the project is deployed in production. diff --git a/{{cookiecutter.project_slug}}/docs/docker_ec2.rst b/{{cookiecutter.project_slug}}/docs/docker_ec2.rst deleted file mode 100644 index 606d2956..00000000 --- a/{{cookiecutter.project_slug}}/docs/docker_ec2.rst +++ /dev/null @@ -1,186 +0,0 @@ -Developing with Docker -====================== - -You can develop your application in a `Docker`_ container for simpler deployment onto bare Linux machines later. This instruction assumes an `Amazon Web Services`_ EC2 instance, but it should work on any machine with Docker > 1.3 and `Docker compose`_ installed. - -.. _Docker: https://www.docker.com/ -.. _Amazon Web Services: http://aws.amazon.com/ -.. _Docker compose: https://docs.docker.com/compose/ - -Setting up -^^^^^^^^^^ - -Docker encourages running one container for each process. This might mean one container for your web server, one for Django application and a third for your database. Once you're happy composing containers in this way you can easily add more, such as a `Redis`_ cache. - -.. _Redis: http://redis.io/ - -The Docker compose tool (previously known as `fig`_) makes linking these containers easy. An example set up for your Cookiecutter Django project might look like this: - -.. _fig: http://www.fig.sh/ - -:: - - webapp/ # Your cookiecutter project would be in here - Dockerfile - ... - database/ - Dockerfile - ... - webserver/ - Dockerfile - ... - production.yml - -Each component of your application would get its own `Dockerfile`_. The rest of this example assumes you are using the `base postgres image`_ for your database. Your database settings in `config/base.py` might then look something like: - -.. _Dockerfile: https://docs.docker.com/reference/builder/ -.. _base postgres image: https://registry.hub.docker.com/_/postgres/ - -.. code-block:: python - - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'postgres', - 'USER': 'postgres', - 'HOST': 'database', - 'PORT': 5432, - } - } - -The `Docker compose documentation`_ explains in detail what you can accomplish in the `production.yml` file, but an example configuration might look like this: - -.. _Docker compose documentation: https://docs.docker.com/compose/#compose-documentation - -.. code-block:: yaml - - database: - build: database - webapp: - build: webapp: - command: /usr/bin/python3.6 manage.py runserver 0.0.0.0:8000 # dev setting - # command: gunicorn -b 0.0.0.0:8000 wsgi:application # production setting - volumes: - - webapp/your_project_name:/path/to/container/workdir/ - links: - - database - webserver: - build: webserver - ports: - - "80:80" - - "443:443" - links: - - webapp - -We'll ignore the webserver for now (you'll want to comment that part out while we do). A working Dockerfile to run your cookiecutter application might look like this: - -:: - - FROM ubuntu:14.04 - ENV REFRESHED_AT 2015-01-13 - - # update packages and prepare to build software - RUN ["apt-get", "update"] - RUN ["apt-get", "-y", "install", "build-essential", "vim", "git", "curl"] - RUN ["locale-gen", "en_GB.UTF-8"] - - # install latest python - RUN ["apt-get", "-y", "build-dep", "python3-dev", "python3-imaging"] - RUN ["apt-get", "-y", "install", "python3-dev", "python3-imaging", "python3-pip"] - - # prepare postgreSQL support - RUN ["apt-get", "-y", "build-dep", "python3-psycopg2"] - - # move into our working directory - # ADD must be after chown see http://stackoverflow.com/a/26145444/1281947 - RUN ["groupadd", "python"] - RUN ["useradd", "python", "-s", "/bin/bash", "-m", "-g", "python", "-G", "python"] - ENV HOME /home/python - WORKDIR /home/python - RUN ["chown", "-R", "python:python", "/home/python"] - ADD ./ /home/python - - # manage requirements - ENV REQUIREMENTS_REFRESHED_AT 2015-02-25 - RUN ["pip3", "install", "-r", "requirements.txt"] - - # uncomment the line below to use container as a non-root user - USER python:python - -Running `sudo docker-compose -f production.yml build` will follow the instructions in your `production.yml` file and build the database container, then your webapp, before mounting your cookiecutter project files as a volume in the webapp container and linking to the database. Our example yaml file runs in development mode but changing it to production mode is as simple as commenting out the line using `runserver` and uncommenting the line using `gunicorn`. - -Both are set to run on port `0.0.0.0:8000`, which is where the Docker daemon will discover it. You can now run `sudo docker-compose -f production.yml up` and browse to `localhost:8000` to see your application running. - -Deployment -^^^^^^^^^^ - -You'll need a webserver container for deployment. An example setup for `Nginx`_ might look like this: - -.. _Nginx: http://wiki.nginx.org/Main - -:: - - FROM ubuntu:14.04 - ENV REFRESHED_AT 2015-02-11 - - # get the nginx package and set it up - RUN ["apt-get", "update"] - RUN ["apt-get", "-y", "install", "nginx"] - - # forward request and error logs to docker log collector - RUN ln -sf /dev/stdout /var/log/nginx/access.log - RUN ln -sf /dev/stderr /var/log/nginx/error.log - VOLUME ["/var/cache/nginx"] - EXPOSE 80 443 - - # load nginx conf - ADD ./site.conf /etc/nginx/sites-available/your_cookiecutter_project - RUN ["ln", "-s", "/etc/nginx/sites-available/your_cookiecutter_project", "/etc/nginx/sites-enabled/your_cookiecutter_project"] - RUN ["rm", "-rf", "/etc/nginx/sites-available/default"] - - #start the server - CMD ["nginx", "-g", "daemon off;"] - -That Dockerfile assumes you have an Nginx conf file named `site.conf` in the same directory as the webserver Dockerfile. A very basic example, which forwards traffic onto the development server or gunicorn for processing, would look like this: - -:: - - # see http://serverfault.com/questions/577370/how-can-i-use-environment-variables-in-nginx-conf#comment730384_577370 - upstream localhost { - server webapp_1:8000; - } - server { - location / { - proxy_pass http://localhost; - } - } - -Running `sudo docker-compose -f production.yml build webserver` will build your server container. Running `sudo docker-compose -f production.yml up` will now expose your application directly on `localhost` (no need to specify the port number). - -Building and running your app on EC2 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -All you now need to do to run your app in production is: - -* Create an empty EC2 Linux instance (any Linux machine should do). - -* Install your preferred source control solution, Docker and Docker compose on the news instance. - -* Pull in your code from source control. The root directory should be the one with your `production.yml` file in it. - -* Run `sudo docker-compose -f production.yml build` and `sudo docker-compose -f production.yml up`. - -* Assign an `Elastic IP address`_ to your new machine. - -.. _Elastic IP address: https://aws.amazon.com/articles/1346 - -* Point your domain name to the elastic IP. - -**Be careful with Elastic IPs** because, on the AWS free tier, if you assign one and then stop the machine you will incur charges while the machine is down (presumably because you're preventing them allocating the IP to someone else). - -Security advisory -^^^^^^^^^^^^^^^^^ - -The setup described in this instruction will get you up-and-running but it hasn't been audited for security. If you are running your own setup like this it is always advisable to, at a minimum, examine your application with a tool like `OWASP ZAP`_ to see what security holes you might be leaving open. - -.. _OWASP ZAP: https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project diff --git a/{{cookiecutter.project_slug}}/docs/index.rst b/{{cookiecutter.project_slug}}/docs/index.rst index 21ef98ee..96752d80 100644 --- a/{{cookiecutter.project_slug}}/docs/index.rst +++ b/{{cookiecutter.project_slug}}/docs/index.rst @@ -3,23 +3,17 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to {{ cookiecutter.project_name }}'s documentation! +{{ cookiecutter.project_name }} Project Documentation ==================================================================== -Contents: +Table of Contents: .. toctree:: :maxdepth: 2 - install - deploy - docker_ec2 - tests - - -Indices and tables -================== +Indices & Tables +================ * :ref:`genindex` * :ref:`modindex` diff --git a/{{cookiecutter.project_slug}}/docs/install.rst b/{{cookiecutter.project_slug}}/docs/install.rst deleted file mode 100644 index 1bc03335..00000000 --- a/{{cookiecutter.project_slug}}/docs/install.rst +++ /dev/null @@ -1,4 +0,0 @@ -Install -========= - -This is where you write how to get a new laptop to run this project. From 867e2ad629a03a5678dc5bea87fcd06b94099599 Mon Sep 17 00:00:00 2001 From: Demetris Stavrou Date: Thu, 21 Jun 2018 23:11:08 +0300 Subject: [PATCH 002/126] Redis config in local is now conditional on Celery. --- {{cookiecutter.project_slug}}/.envs/.local/.django | 2 ++ 1 file changed, 2 insertions(+) diff --git a/{{cookiecutter.project_slug}}/.envs/.local/.django b/{{cookiecutter.project_slug}}/.envs/.local/.django index 8aa9a994..a145c6bc 100644 --- a/{{cookiecutter.project_slug}}/.envs/.local/.django +++ b/{{cookiecutter.project_slug}}/.envs/.local/.django @@ -2,6 +2,8 @@ # ------------------------------------------------------------------------------ USE_DOCKER=yes +{%- if cookiecutter.use_celery == 'y' %} # Redis # ------------------------------------------------------------------------------ REDIS_URL=redis://redis:6379/0 +{% endif %} From 6f638078ebe6edcf6b1930658ba2ee4451c94c95 Mon Sep 17 00:00:00 2001 From: Demetris Stavrou Date: Fri, 22 Jun 2018 17:32:10 +0300 Subject: [PATCH 003/126] Moved CELERY_BROKER_URL definition to .django env file to resolve error when Celery is not used (PR #1693) --- {{cookiecutter.project_slug}}/.envs/.production/.django | 7 +++++++ .../compose/production/django/entrypoint.sh | 3 --- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/.envs/.production/.django b/{{cookiecutter.project_slug}}/.envs/.production/.django index 2e9eefea..1203ce64 100644 --- a/{{cookiecutter.project_slug}}/.envs/.production/.django +++ b/{{cookiecutter.project_slug}}/.envs/.production/.django @@ -43,3 +43,10 @@ DJANGO_SENTRY_DSN= # Redis # ------------------------------------------------------------------------------ REDIS_URL=redis://redis:6379/0 + +{% if cookiecutter.use_celery == "y" %} +# Celery +# ------------------------------------------------------------------------------ +CELERY_BROKER_URL=redis://redis:6379/0 + +{% endif %} \ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint.sh b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint.sh index 74242bde..ae0858e1 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint.sh +++ b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint.sh @@ -7,9 +7,6 @@ set -o nounset cmd="$@" -# N.B. If only .env files supported variable expansion... -export CELERY_BROKER_URL="${REDIS_URL}" - if [ -z "${POSTGRES_USER}" ]; then base_postgres_image_default_user='postgres' export POSTGRES_USER="${base_postgres_image_default_user}" From 72893b1d0678b9e248e16660e419fbd680b30d4f Mon Sep 17 00:00:00 2001 From: Demetris Stavrou Date: Thu, 21 Jun 2018 23:11:08 +0300 Subject: [PATCH 004/126] Redis config in local is now conditional on Celery. --- {{cookiecutter.project_slug}}/.envs/.local/.django | 2 ++ 1 file changed, 2 insertions(+) diff --git a/{{cookiecutter.project_slug}}/.envs/.local/.django b/{{cookiecutter.project_slug}}/.envs/.local/.django index 8aa9a994..a145c6bc 100644 --- a/{{cookiecutter.project_slug}}/.envs/.local/.django +++ b/{{cookiecutter.project_slug}}/.envs/.local/.django @@ -2,6 +2,8 @@ # ------------------------------------------------------------------------------ USE_DOCKER=yes +{%- if cookiecutter.use_celery == 'y' %} # Redis # ------------------------------------------------------------------------------ REDIS_URL=redis://redis:6379/0 +{% endif %} From 065becf277d1d56207114aeefbb25f85f62a678d Mon Sep 17 00:00:00 2001 From: Demetris Stavrou Date: Fri, 22 Jun 2018 17:32:10 +0300 Subject: [PATCH 005/126] Moved CELERY_BROKER_URL definition to .django env file to resolve error when Celery is not used (PR #1693) --- {{cookiecutter.project_slug}}/.envs/.production/.django | 7 +++++++ .../compose/production/django/entrypoint | 3 --- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/.envs/.production/.django b/{{cookiecutter.project_slug}}/.envs/.production/.django index 5cb90897..34ab71a2 100644 --- a/{{cookiecutter.project_slug}}/.envs/.production/.django +++ b/{{cookiecutter.project_slug}}/.envs/.production/.django @@ -43,3 +43,10 @@ SENTRY_DSN= # Redis # ------------------------------------------------------------------------------ REDIS_URL=redis://redis:6379/0 + +{% if cookiecutter.use_celery == "y" %} +# Celery +# ------------------------------------------------------------------------------ +CELERY_BROKER_URL=redis://redis:6379/0 + +{% endif %} \ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint index 4845e343..e2c22de5 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint +++ b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint @@ -5,9 +5,6 @@ set -o pipefail set -o nounset -# N.B. If only .env files supported variable expansion... -export CELERY_BROKER_URL="${REDIS_URL}" - if [ -z "${POSTGRES_USER}" ]; then base_postgres_image_default_user='postgres' export POSTGRES_USER="${base_postgres_image_default_user}" From c3026e7dfbf94960bc7416bf782dc69285cc0de1 Mon Sep 17 00:00:00 2001 From: Demetris Stavrou Date: Wed, 27 Jun 2018 23:36:06 +0300 Subject: [PATCH 006/126] Added CELERY_BROKER_URL back to entrypoint and surrounded it with a conditional --- .../compose/production/django/entrypoint | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint index e2c22de5..0a76b310 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint +++ b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint @@ -5,6 +5,11 @@ set -o pipefail set -o nounset +{% if cookiecutter.use_celery == 'y' %} +# N.B. If only .env files supported variable expansion... +export CELERY_BROKER_URL="${REDIS_URL}" +{% endif %} + if [ -z "${POSTGRES_USER}" ]; then base_postgres_image_default_user='postgres' export POSTGRES_USER="${base_postgres_image_default_user}" From d79f122bc93346ec2f8cbbe5fab6922737060321 Mon Sep 17 00:00:00 2001 From: Demetris Stavrou Date: Thu, 21 Jun 2018 23:11:08 +0300 Subject: [PATCH 007/126] Redis config in local is now conditional on Celery. --- {{cookiecutter.project_slug}}/.envs/.local/.django | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/.envs/.local/.django b/{{cookiecutter.project_slug}}/.envs/.local/.django index d94a17e5..6f7a2b11 100644 --- a/{{cookiecutter.project_slug}}/.envs/.local/.django +++ b/{{cookiecutter.project_slug}}/.envs/.local/.django @@ -2,10 +2,11 @@ # ------------------------------------------------------------------------------ USE_DOCKER=yes +{%- if cookiecutter.use_celery == 'y' %} # Redis # ------------------------------------------------------------------------------ REDIS_URL=redis://redis:6379/0 -{% if cookiecutter.use_celery == 'y' %} + # Celery # ------------------------------------------------------------------------------ From 7c69704f9fe3351be10f976e6eb26f7e98932b33 Mon Sep 17 00:00:00 2001 From: Demetris Stavrou Date: Fri, 22 Jun 2018 17:32:10 +0300 Subject: [PATCH 008/126] Moved CELERY_BROKER_URL definition to .django env file to resolve error when Celery is not used (PR #1693) --- .../compose/production/django/entrypoint | 3 --- 1 file changed, 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint index 4845e343..e2c22de5 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint +++ b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint @@ -5,9 +5,6 @@ set -o pipefail set -o nounset -# N.B. If only .env files supported variable expansion... -export CELERY_BROKER_URL="${REDIS_URL}" - if [ -z "${POSTGRES_USER}" ]; then base_postgres_image_default_user='postgres' export POSTGRES_USER="${base_postgres_image_default_user}" From 2c56b2e0e30196b2f89582a640170b3a5fae0145 Mon Sep 17 00:00:00 2001 From: Demetris Stavrou Date: Wed, 27 Jun 2018 23:36:06 +0300 Subject: [PATCH 009/126] Added CELERY_BROKER_URL back to entrypoint and surrounded it with a conditional --- .../compose/production/django/entrypoint | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint index e2c22de5..0a76b310 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint +++ b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint @@ -5,6 +5,11 @@ set -o pipefail set -o nounset +{% if cookiecutter.use_celery == 'y' %} +# N.B. If only .env files supported variable expansion... +export CELERY_BROKER_URL="${REDIS_URL}" +{% endif %} + if [ -z "${POSTGRES_USER}" ]; then base_postgres_image_default_user='postgres' export POSTGRES_USER="${base_postgres_image_default_user}" From 1c5c4e52c02bbe8df3bbae381e333806f0919c95 Mon Sep 17 00:00:00 2001 From: yunti Date: Mon, 11 Mar 2019 21:05:31 +0000 Subject: [PATCH 010/126] Add automatic migrations to heroku deploys (#1951) heroku now has a new feature for running tasks as part of deployment. Perfect for automatic migrations. https://devcenter.heroku.com/articles/release-phase#specifying-release-phase-tasks --- docs/deployment-on-heroku.rst | 1 - {{cookiecutter.project_slug}}/Procfile | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment-on-heroku.rst b/docs/deployment-on-heroku.rst index f753aa5a..5acb44fa 100644 --- a/docs/deployment-on-heroku.rst +++ b/docs/deployment-on-heroku.rst @@ -47,7 +47,6 @@ Run these commands to deploy the project to Heroku: git push heroku master - heroku run python manage.py migrate heroku run python manage.py createsuperuser heroku run python manage.py collectstatic --no-input diff --git a/{{cookiecutter.project_slug}}/Procfile b/{{cookiecutter.project_slug}}/Procfile index c77d76d9..d9319f5c 100644 --- a/{{cookiecutter.project_slug}}/Procfile +++ b/{{cookiecutter.project_slug}}/Procfile @@ -1,3 +1,4 @@ +release: python manage.py migrate web: gunicorn config.wsgi:application {% if cookiecutter.use_celery == "y" -%} worker: celery worker --app={{cookiecutter.project_slug}}.taskapp --loglevel=info From eb85627d1a30ea3417ec42b034bce41f71d3f0cd Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 11 Mar 2019 22:02:11 +0000 Subject: [PATCH 011/126] Update to latest bug fix for Python 3.6 to fix Heroku warning when deploying Python has released a security update! Please consider upgrading to python-3.6.8 Learn More: https://devcenter.heroku.com/articles/python-runtimes --- {{cookiecutter.project_slug}}/runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/runtime.txt b/{{cookiecutter.project_slug}}/runtime.txt index 1935e977..9fbd3bf0 100644 --- a/{{cookiecutter.project_slug}}/runtime.txt +++ b/{{cookiecutter.project_slug}}/runtime.txt @@ -1 +1 @@ -python-3.6.6 +python-3.6.8 From 6213af4b562f640362c95f9c8386cec597e8600d Mon Sep 17 00:00:00 2001 From: Oleg Russkin Date: Tue, 12 Mar 2019 16:35:03 +0200 Subject: [PATCH 012/126] Update redis to 3.2.0 Related bug was fixed: celery/kombu#947 Moreover, recent kombu versiones demand such redis version. --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index e43b70af..0a9144ec 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -8,7 +8,7 @@ argon2-cffi==19.1.0 # https://github.com/hynek/argon2_cffi {%- if cookiecutter.use_whitenoise == 'y' %} whitenoise==4.1.2 # https://github.com/evansd/whitenoise {%- endif %} -redis>=2.10.6, < 3 # pyup: < 3 # https://github.com/antirez/redis +redis>=3.2.0 # https://github.com/antirez/redis {%- if cookiecutter.use_celery == "y" %} celery==4.2.1 # pyup: < 5.0 # https://github.com/celery/celery {%- if cookiecutter.use_docker == 'y' %} From 638c93d1dff45849b531e2633d0369f7ac130567 Mon Sep 17 00:00:00 2001 From: Oleg Russkin Date: Tue, 12 Mar 2019 16:38:43 +0200 Subject: [PATCH 013/126] Add kombu to base (celery) dependencies Using latest version 4.4.0, previous suitable 4.3.0 also had bug: kombu/issues#1006 --- {{cookiecutter.project_slug}}/requirements/base.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 0a9144ec..605ff19c 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -11,6 +11,7 @@ whitenoise==4.1.2 # https://github.com/evansd/whitenoise redis>=3.2.0 # https://github.com/antirez/redis {%- if cookiecutter.use_celery == "y" %} celery==4.2.1 # pyup: < 5.0 # https://github.com/celery/celery +kombu==4.4.0 # https://github.com/celery/kombu {%- if cookiecutter.use_docker == 'y' %} flower==0.9.2 # https://github.com/mher/flower {%- endif %} From 8ab63940ec9b151f03f99f6aff3e84eae973b47b Mon Sep 17 00:00:00 2001 From: Oleg Russkin Date: Tue, 12 Mar 2019 16:49:24 +0200 Subject: [PATCH 014/126] Contributors: Add Oleg Russkin --- CONTRIBUTORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index dc41463f..2a26e212 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -145,6 +145,7 @@ Listed in alphabetical order. Mesut Yılmaz `@myilmaz`_ Michael Gecht `@mimischi`_ @_mischi mozillazg `@mozillazg`_ + Oleg Russkin `@rolep`_ Pablo `@oubiga`_ Parbhat Puri `@parbhat`_ Peter Bittner `@bittner`_ From 8ce3e6605bf819b18262de7d71eec4ee53c235c1 Mon Sep 17 00:00:00 2001 From: anuj Date: Wed, 13 Mar 2019 14:22:36 +0530 Subject: [PATCH 015/126] Added link for Google Cloud storage blog --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index b9e71ace..de271080 100644 --- a/README.rst +++ b/README.rst @@ -279,6 +279,7 @@ experience better. Articles --------- +* `Using cookiecutter-django with Google Cloud Storage`_ - Mar. 12, 2019 * `cookiecutter-django with Nginx, Route 53 and ELB`_ - Feb. 12, 2018 * `cookiecutter-django and Amazon RDS`_ - Feb. 7, 2018 * `Deploying Cookiecutter-Django with Docker-Compose`_ - Oct. 19, 2017 @@ -292,6 +293,7 @@ Articles Have a blog or online publication? Write about your cookiecutter-django tips and tricks, then send us a pull request with the link. +.. _`Using cookiecutter-django with Google Cloud Storage`: https://ahhda.github.io/cloud/gce/django/2019/03/12/using-django-cookiecutter-cloud-storage.html .. _`cookiecutter-django with Nginx, Route 53 and ELB`: https://msaizar.com/blog/cookiecutter-django-nginx-route-53-and-elb/ .. _`cookiecutter-django and Amazon RDS`: https://msaizar.com/blog/cookiecutter-django-and-amazon-rds/ .. _`Deploying Cookiecutter-Django with Docker-Compose`: http://adamantine.me/2017/10/19/deploying-cookiecutter-django-with-docker-compose/ From 4550e4aa373a7069f14eda956f602d98736eed5f Mon Sep 17 00:00:00 2001 From: anuj Date: Wed, 13 Mar 2019 14:31:35 +0530 Subject: [PATCH 016/126] Remove link that does not exist --- README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.rst b/README.rst index b9e71ace..8ce39ab2 100644 --- a/README.rst +++ b/README.rst @@ -281,7 +281,6 @@ Articles * `cookiecutter-django with Nginx, Route 53 and ELB`_ - Feb. 12, 2018 * `cookiecutter-django and Amazon RDS`_ - Feb. 7, 2018 -* `Deploying Cookiecutter-Django with Docker-Compose`_ - Oct. 19, 2017 * `Using Cookiecutter to Jumpstart a Django Project on Windows with PyCharm`_ - May 19, 2017 * `Exploring with Cookiecutter`_ - Dec. 3, 2016 * `Introduction to Cookiecutter-Django`_ - Feb. 19, 2016 @@ -294,7 +293,6 @@ Have a blog or online publication? Write about your cookiecutter-django tips and .. _`cookiecutter-django with Nginx, Route 53 and ELB`: https://msaizar.com/blog/cookiecutter-django-nginx-route-53-and-elb/ .. _`cookiecutter-django and Amazon RDS`: https://msaizar.com/blog/cookiecutter-django-and-amazon-rds/ -.. _`Deploying Cookiecutter-Django with Docker-Compose`: http://adamantine.me/2017/10/19/deploying-cookiecutter-django-with-docker-compose/ .. _`Exploring with Cookiecutter`: http://www.snowboardingcoder.com/django/2016/12/03/exploring-with-cookiecutter/ .. _`Using Cookiecutter to Jumpstart a Django Project on Windows with PyCharm`: https://joshuahunter.com/posts/using-cookiecutter-to-jumpstart-a-django-project-on-windows-with-pycharm/ From 2edd51aa77f97ba2531c863ce2d3d65d544257a7 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 13 Mar 2019 05:37:54 -0400 Subject: [PATCH 017/126] Update pytest from 4.3.0 to 4.3.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 37a96913..1d0823b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,6 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ tox==3.6.1 -pytest==4.3.0 +pytest==4.3.1 pytest-cookies==0.3.0 pyyaml==3.13 From b142713ec666ca624f93f4f79ad41cec3bdab821 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Wed, 13 Mar 2019 14:31:17 +0000 Subject: [PATCH 018/126] Remove running collectstatic from Heroku docs, it's done during deployments --- docs/deployment-on-heroku.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/deployment-on-heroku.rst b/docs/deployment-on-heroku.rst index 5acb44fa..09953cf8 100644 --- a/docs/deployment-on-heroku.rst +++ b/docs/deployment-on-heroku.rst @@ -48,7 +48,6 @@ Run these commands to deploy the project to Heroku: git push heroku master heroku run python manage.py createsuperuser - heroku run python manage.py collectstatic --no-input heroku run python manage.py check --deploy From aee746b5a2b4308a71371cd2983ad3ea9a1c2a4d Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 13 Mar 2019 10:40:27 -0700 Subject: [PATCH 019/126] Update pyyaml from 3.13 to 5.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1d0823b5..647bccae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,4 @@ flake8==3.7.6 tox==3.6.1 pytest==4.3.1 pytest-cookies==0.3.0 -pyyaml==3.13 +pyyaml==5.1 From 02c19193a0a54800dfaaea75c39d52f23a5a12d8 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 18 Mar 2019 09:54:39 +0000 Subject: [PATCH 020/126] Specify requirements file in Pyup config --- .pyup.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .pyup.yml diff --git a/.pyup.yml b/.pyup.yml new file mode 100644 index 00000000..4eab42d5 --- /dev/null +++ b/.pyup.yml @@ -0,0 +1,6 @@ +# Specify requirement files by hand +requirements: + - requirements.txt + - {{cookiecutter.project_slug}}/requirements/base.txt + - {{cookiecutter.project_slug}}/requirements/local.txt + - {{cookiecutter.project_slug}}/requirements/production.txt From a4a7c6488f79bba6c2c556ab6dbfee4f7e242655 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 18 Mar 2019 09:56:20 +0000 Subject: [PATCH 021/126] Fix syntax in PyUP config file --- .pyup.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.pyup.yml b/.pyup.yml index 4eab42d5..b368b664 100644 --- a/.pyup.yml +++ b/.pyup.yml @@ -1,6 +1,18 @@ # Specify requirement files by hand requirements: - - requirements.txt - - {{cookiecutter.project_slug}}/requirements/base.txt - - {{cookiecutter.project_slug}}/requirements/local.txt - - {{cookiecutter.project_slug}}/requirements/production.txt + - requirements.txt: + # update all dependencies and pin them + update: all + pin: True + - {{cookiecutter.project_slug}}/requirements/base.txt: + # update all dependencies and pin them + update: all + pin: True + - {{cookiecutter.project_slug}}/requirements/local.txt: + # update all dependencies and pin them + update: all + pin: True + - {{cookiecutter.project_slug}}/requirements/production.txt: + # update all dependencies and pin them + update: all + pin: True From 135c6d7f595a7828201987657f16f8c6fc798ba4 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 18 Mar 2019 09:59:13 +0000 Subject: [PATCH 022/126] Fix syntax error in PyUP config - take 2 --- .pyup.yml | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/.pyup.yml b/.pyup.yml index b368b664..9f78cf8c 100644 --- a/.pyup.yml +++ b/.pyup.yml @@ -1,18 +1,6 @@ # Specify requirement files by hand requirements: - - requirements.txt: - # update all dependencies and pin them - update: all - pin: True - - {{cookiecutter.project_slug}}/requirements/base.txt: - # update all dependencies and pin them - update: all - pin: True - - {{cookiecutter.project_slug}}/requirements/local.txt: - # update all dependencies and pin them - update: all - pin: True - - {{cookiecutter.project_slug}}/requirements/production.txt: - # update all dependencies and pin them - update: all - pin: True + - "requirements.txt" + - "{{cookiecutter.project_slug}}/requirements/base.txt" + - "{{cookiecutter.project_slug}}/requirements/local.txt" + - "{{cookiecutter.project_slug}}/requirements/production.txt" From 43a6f5d854d1cc8ef2afb3d78067fcb8d08a76c7 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 18 Mar 2019 10:03:32 +0000 Subject: [PATCH 023/126] Update .pyup.yml --- .pyup.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.pyup.yml b/.pyup.yml index 9f78cf8c..4978524e 100644 --- a/.pyup.yml +++ b/.pyup.yml @@ -1,4 +1,15 @@ -# Specify requirement files by hand +# configure updates globally +# default: all +# allowed: all, insecure, False +update: all + +# configure dependency pinning globally +# default: True +# allowed: True, False +pin: True + +# Specify requirement files by hand, pyup seems to struggle to +# find the ones in the project_slug folder requirements: - "requirements.txt" - "{{cookiecutter.project_slug}}/requirements/base.txt" From 68f7268770057752609dd1f6beca4d432eb9f2a5 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 18 Mar 2019 17:49:43 +0000 Subject: [PATCH 024/126] Run Black on Travis (#1957) * Create a test matrix on Travis CI to help testing multiple options * Change test_docker.sh to fail if any command in it fails * Run black on the CI with --check option * Fix formatting of project files using black * Install black in the docker container * Exclude migrations in black checks * Fix Black formatting violations * Run black on the whole generated project & fix issues --- .travis.yml | 16 +- hooks/post_gen_project.py | 54 ++-- hooks/pre_gen_project.py | 10 +- tests/test_cookiecutter_generation.py | 4 +- tests/test_docker.sh | 7 +- tox.ini | 6 +- .../config/settings/base.py | 206 +++++++-------- .../config/settings/local.py | 48 ++-- .../config/settings/production.py | 249 +++++++++--------- .../config/settings/test.py | 8 +- {{cookiecutter.project_slug}}/config/urls.py | 13 +- {{cookiecutter.project_slug}}/config/wsgi.py | 11 +- .../requirements/local.txt | 1 + .../taskapp/celery.py | 18 +- .../users/adapters.py | 2 - .../users/forms.py | 1 - .../users/tests/factories.py | 4 +- .../users/tests/test_forms.py | 1 - .../users/tests/test_views.py | 1 - 19 files changed, 328 insertions(+), 332 deletions(-) diff --git a/.travis.yml b/.travis.yml index a46726d6..65b2a28d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,16 +7,20 @@ language: python python: 3.6 -env: - - TOX_ENV=py36 - before_install: - docker-compose -v - docker -v -script: - - tox -e $TOX_ENV - - sh tests/test_docker.sh +matrix: + include: + - name: Test + script: tox -e py36 + - name: Black + script: tox -e black + - name: Basic Docker + script: sh tests/test_docker.sh + - name: Docker with Celery + script: sh tests/test_docker.sh use_celery=y install: - pip install tox diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 45435dd0..a9c1c941 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -32,10 +32,7 @@ DEBUG_VALUE = "debug" def remove_open_source_files(): - file_names = [ - "CONTRIBUTORS.txt", - "LICENSE", - ] + file_names = ["CONTRIBUTORS.txt", "LICENSE"] for file_name in file_names: os.remove(file_name) @@ -71,7 +68,10 @@ 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": + 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) @@ -183,11 +183,7 @@ def generate_postgres_user(debug=False): def set_postgres_user(file_path, value): - postgres_user = set_flag( - file_path, - "!!!SET POSTGRES_USER!!!", - value=value, - ) + postgres_user = set_flag(file_path, "!!!SET POSTGRES_USER!!!", value=value) return postgres_user @@ -205,9 +201,7 @@ def set_postgres_password(file_path, value=None): def set_celery_flower_user(file_path, value): celery_flower_user = set_flag( - file_path, - "!!!SET CELERY_FLOWER_USER!!!", - value=value, + file_path, "!!!SET CELERY_FLOWER_USER!!!", value=value ) return celery_flower_user @@ -230,11 +224,7 @@ def append_to_gitignore_file(s): gitignore_file.write(os.linesep) -def set_flags_in_envs( - postgres_user, - celery_flower_user, - debug=False, -): +def set_flags_in_envs(postgres_user, celery_flower_user, debug=False): local_django_envs_path = os.path.join(".envs", ".local", ".django") production_django_envs_path = os.path.join(".envs", ".production", ".django") local_postgres_envs_path = os.path.join(".envs", ".local", ".postgres") @@ -244,14 +234,22 @@ def set_flags_in_envs( set_django_admin_url(production_django_envs_path) set_postgres_user(local_postgres_envs_path, value=postgres_user) - set_postgres_password(local_postgres_envs_path, value=DEBUG_VALUE if debug else None) + set_postgres_password( + local_postgres_envs_path, value=DEBUG_VALUE if debug else None + ) set_postgres_user(production_postgres_envs_path, value=postgres_user) - set_postgres_password(production_postgres_envs_path, value=DEBUG_VALUE if debug else None) + set_postgres_password( + production_postgres_envs_path, value=DEBUG_VALUE if debug else None + ) set_celery_flower_user(local_django_envs_path, value=celery_flower_user) - set_celery_flower_password(local_django_envs_path, value=DEBUG_VALUE if debug else None) + set_celery_flower_password( + local_django_envs_path, value=DEBUG_VALUE if debug else None + ) set_celery_flower_user(production_django_envs_path, value=celery_flower_user) - set_celery_flower_password(production_django_envs_path, value=DEBUG_VALUE if debug else None) + set_celery_flower_password( + production_django_envs_path, value=DEBUG_VALUE if debug else None + ) def set_flags_in_settings_files(): @@ -302,8 +300,8 @@ def main(): if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y": print( INFO + ".env(s) are only utilized when Docker Compose and/or " - "Heroku support is enabled so keeping them does not " - "make sense given your current setup." + TERMINATOR + "Heroku support is enabled so keeping them does not " + "make sense given your current setup." + TERMINATOR ) remove_envs_and_associated_files() else: @@ -325,10 +323,10 @@ def main(): "{{ cookiecutter.js_task_runner }}".lower().capitalize() ) + "working together not supported yet. " - "You can continue using the generated project like you " - "normally would, however you would need to add a JS " - "task runner service to your Docker Compose configuration " - "manually." + TERMINATOR + "You can continue using the generated project like you " + "normally would, however you would need to add a JS " + "task runner service to your Docker Compose configuration " + "manually." + TERMINATOR ) if "{{ cookiecutter.use_celery }}".lower() == "n": diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index b7f4dfbb..a6b83455 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -18,11 +18,13 @@ SUCCESS = "\x1b[1;32m [SUCCESS]: " project_slug = "{{ cookiecutter.project_slug }}" if hasattr(project_slug, "isidentifier"): - assert project_slug.isidentifier(), "'{}' project slug is not a valid Python identifier.".format( - project_slug - ) + assert ( + project_slug.isidentifier() + ), "'{}' project slug is not a valid Python identifier.".format(project_slug) -assert "\\" not in "{{ cookiecutter.author_name }}", "Don't include backslashes in author name." +assert ( + "\\" not in "{{ cookiecutter.author_name }}" +), "Don't include backslashes in author name." if "{{ cookiecutter.use_docker }}".lower() == "n": python_major_version = sys.version_info[0] diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index b2c235a8..3010d364 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -97,8 +97,8 @@ def test_travis_invokes_pytest(cookies, context): assert result.project.basename == context["project_slug"] assert result.project.isdir() - with open(f'{result.project}/.travis.yml', 'r') as travis_yml: + with open(f"{result.project}/.travis.yml", "r") as travis_yml: try: - assert yaml.load(travis_yml)['script'] == ['pytest'] + assert yaml.load(travis_yml)["script"] == ["pytest"] except yaml.YAMLError as e: pytest.fail(e) diff --git a/tests/test_docker.sh b/tests/test_docker.sh index eddfe98c..55771c14 100755 --- a/tests/test_docker.sh +++ b/tests/test_docker.sh @@ -3,6 +3,8 @@ # it is meant to be run from the root directory of the repository, eg: # sh tests/test_docker.sh +set -o errexit + # install test requirements pip install -r requirements.txt @@ -11,12 +13,15 @@ mkdir -p .cache/docker cd .cache/docker # create the project using the default settings in cookiecutter.json -cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y +cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y $@ cd my_awesome_project # run the project's type checks docker-compose -f local.yml run django mypy my_awesome_project +# Run black with --check option +docker-compose -f local.yml run django black --check --diff --exclude 'migrations' ./ + # run the project's tests docker-compose -f local.yml run django pytest diff --git a/tox.ini b/tox.ini index 040c8a41..cef3efc7 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,11 @@ [tox] skipsdist = true -envlist = py36 +envlist = py36,black [testenv] deps = -rrequirements.txt commands = pytest {posargs:./tests} + +[testenv:black] +deps = black +commands = black --check hooks tests setup.py docs diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py index 950b9ed7..848af8e8 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -4,27 +4,29 @@ Base settings to build other settings files upon. import environ -ROOT_DIR = environ.Path(__file__) - 3 # ({{ cookiecutter.project_slug }}/config/settings/base.py - 3 = {{ cookiecutter.project_slug }}/) -APPS_DIR = ROOT_DIR.path('{{ cookiecutter.project_slug }}') +ROOT_DIR = ( + environ.Path(__file__) - 3 +) # ({{ cookiecutter.project_slug }}/config/settings/base.py - 3 = {{ cookiecutter.project_slug }}/) +APPS_DIR = ROOT_DIR.path("{{ cookiecutter.project_slug }}") env = environ.Env() -READ_DOT_ENV_FILE = env.bool('DJANGO_READ_DOT_ENV_FILE', default=False) +READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=False) if READ_DOT_ENV_FILE: # OS environment variables take precedence over variables from .env - env.read_env(str(ROOT_DIR.path('.env'))) + env.read_env(str(ROOT_DIR.path(".env"))) # GENERAL # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#debug -DEBUG = env.bool('DJANGO_DEBUG', False) +DEBUG = env.bool("DJANGO_DEBUG", False) # Local time zone. Choices are # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # though not all of them may be available with every OS. # In Windows, this must be set to your system time zone. -TIME_ZONE = '{{ cookiecutter.timezone }}' +TIME_ZONE = "{{ cookiecutter.timezone }}" # https://docs.djangoproject.com/en/dev/ref/settings/#language-code -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" # https://docs.djangoproject.com/en/dev/ref/settings/#site-id SITE_ID = 1 # https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n @@ -37,45 +39,45 @@ USE_TZ = True # DATABASES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#databases -{% if cookiecutter.use_docker == 'y' -%} -DATABASES = { - 'default': env.db('DATABASE_URL'), -} +{% if cookiecutter.use_docker == "y" -%} +DATABASES = {"default": env.db("DATABASE_URL")} {%- else %} DATABASES = { - 'default': env.db('DATABASE_URL', default='postgres://{% if cookiecutter.windows == 'y' %}localhost{% endif %}/{{cookiecutter.project_slug}}'), + "default": env.db( + "DATABASE_URL", default="postgres://{% if cookiecutter.windows == 'y' %}localhost{% endif %}/{{cookiecutter.project_slug}}" + ), } {%- endif %} -DATABASES['default']['ATOMIC_REQUESTS'] = True +DATABASES["default"]["ATOMIC_REQUESTS"] = True # URLS # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf -ROOT_URLCONF = 'config.urls' +ROOT_URLCONF = "config.urls" # https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application -WSGI_APPLICATION = 'config.wsgi.application' +WSGI_APPLICATION = "config.wsgi.application" # APPS # ------------------------------------------------------------------------------ DJANGO_APPS = [ - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.messages', - 'django.contrib.staticfiles', - # 'django.contrib.humanize', # Handy template tags - 'django.contrib.admin', + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.sites", + "django.contrib.messages", + "django.contrib.staticfiles", + # "django.contrib.humanize", # Handy template tags + "django.contrib.admin", ] THIRD_PARTY_APPS = [ - 'crispy_forms', - 'allauth', - 'allauth.account', - 'allauth.socialaccount', - 'rest_framework', + "crispy_forms", + "allauth", + "allauth.account", + "allauth.socialaccount", + "rest_framework", ] LOCAL_APPS = [ - '{{ cookiecutter.project_slug }}.users.apps.UsersAppConfig', + "{{ cookiecutter.project_slug }}.users.apps.UsersAppConfig", # Your stuff: custom apps go here ] # https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps @@ -84,86 +86,76 @@ INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS # MIGRATIONS # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#migration-modules -MIGRATION_MODULES = { - 'sites': '{{ cookiecutter.project_slug }}.contrib.sites.migrations' -} +MIGRATION_MODULES = {"sites": "{{ cookiecutter.project_slug }}.contrib.sites.migrations"} # AUTHENTICATION # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#authentication-backends AUTHENTICATION_BACKENDS = [ - 'django.contrib.auth.backends.ModelBackend', - 'allauth.account.auth_backends.AuthenticationBackend', + "django.contrib.auth.backends.ModelBackend", + "allauth.account.auth_backends.AuthenticationBackend", ] # https://docs.djangoproject.com/en/dev/ref/settings/#auth-user-model -AUTH_USER_MODEL = 'users.User' +AUTH_USER_MODEL = "users.User" # https://docs.djangoproject.com/en/dev/ref/settings/#login-redirect-url -LOGIN_REDIRECT_URL = 'users:redirect' +LOGIN_REDIRECT_URL = "users:redirect" # https://docs.djangoproject.com/en/dev/ref/settings/#login-url -LOGIN_URL = 'account_login' +LOGIN_URL = "account_login" # PASSWORDS # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#password-hashers PASSWORD_HASHERS = [ # https://docs.djangoproject.com/en/dev/topics/auth/passwords/#using-argon2-with-django - 'django.contrib.auth.hashers.Argon2PasswordHasher', - 'django.contrib.auth.hashers.PBKDF2PasswordHasher', - 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', - 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', - 'django.contrib.auth.hashers.BCryptPasswordHasher', + "django.contrib.auth.hashers.Argon2PasswordHasher", + "django.contrib.auth.hashers.PBKDF2PasswordHasher", + "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", + "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", + "django.contrib.auth.hashers.BCryptPasswordHasher", ] # https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" }, + {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, + {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, + {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, ] # MIDDLEWARE # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#middleware MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] # STATIC # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#static-root -STATIC_ROOT = str(ROOT_DIR('staticfiles')) +STATIC_ROOT = str(ROOT_DIR("staticfiles")) # https://docs.djangoproject.com/en/dev/ref/settings/#static-url -STATIC_URL = '/static/' +STATIC_URL = "/static/" # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS -STATICFILES_DIRS = [ - str(APPS_DIR.path('static')), -] +STATICFILES_DIRS = [str(APPS_DIR.path("static"))] # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders STATICFILES_FINDERS = [ - 'django.contrib.staticfiles.finders.FileSystemFinder', - 'django.contrib.staticfiles.finders.AppDirectoriesFinder', + "django.contrib.staticfiles.finders.FileSystemFinder", + "django.contrib.staticfiles.finders.AppDirectoriesFinder", ] # MEDIA # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#media-root -MEDIA_ROOT = str(APPS_DIR('media')) +MEDIA_ROOT = str(APPS_DIR("media")) # https://docs.djangoproject.com/en/dev/ref/settings/#media-url -MEDIA_URL = '/media/' +MEDIA_URL = "/media/" # TEMPLATES # ------------------------------------------------------------------------------ @@ -171,43 +163,39 @@ MEDIA_URL = '/media/' TEMPLATES = [ { # https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND - 'BACKEND': 'django.template.backends.django.DjangoTemplates', + "BACKEND": "django.template.backends.django.DjangoTemplates", # https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs - 'DIRS': [ - str(APPS_DIR.path('templates')), - ], - 'OPTIONS': { + "DIRS": [str(APPS_DIR.path("templates"))], + "OPTIONS": { # https://docs.djangoproject.com/en/dev/ref/settings/#template-debug - 'debug': DEBUG, + "debug": DEBUG, # https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders # https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types - 'loaders': [ - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', + "loaders": [ + "django.template.loaders.filesystem.Loader", + "django.template.loaders.app_directories.Loader", ], # https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.template.context_processors.i18n', - 'django.template.context_processors.media', - 'django.template.context_processors.static', - 'django.template.context_processors.tz', - 'django.contrib.messages.context_processors.messages', + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.template.context_processors.i18n", + "django.template.context_processors.media", + "django.template.context_processors.static", + "django.template.context_processors.tz", + "django.contrib.messages.context_processors.messages", ], }, - }, + } ] # http://django-crispy-forms.readthedocs.io/en/latest/install.html#template-packs -CRISPY_TEMPLATE_PACK = 'bootstrap4' +CRISPY_TEMPLATE_PACK = "bootstrap4" # FIXTURES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#fixture-dirs -FIXTURE_DIRS = ( - str(APPS_DIR.path('fixtures')), -) +FIXTURE_DIRS = (str(APPS_DIR.path("fixtures")),) # SECURITY # ------------------------------------------------------------------------------ @@ -218,41 +206,41 @@ 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' +X_FRAME_OPTIONS = "DENY" # EMAIL # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend -EMAIL_BACKEND = env('DJANGO_EMAIL_BACKEND', default='django.core.mail.backends.smtp.EmailBackend') +EMAIL_BACKEND = env( + "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.smtp.EmailBackend" +) # ADMIN # ------------------------------------------------------------------------------ # Django Admin URL. -ADMIN_URL = 'admin/' +ADMIN_URL = "admin/" # https://docs.djangoproject.com/en/dev/ref/settings/#admins -ADMINS = [ - ("""{{cookiecutter.author_name}}""", '{{cookiecutter.email}}'), -] +ADMINS = [("""{{cookiecutter.author_name}}""", "{{cookiecutter.email}}")] # https://docs.djangoproject.com/en/dev/ref/settings/#managers MANAGERS = ADMINS {% if cookiecutter.use_celery == 'y' -%} # Celery # ------------------------------------------------------------------------------ -INSTALLED_APPS += ['{{cookiecutter.project_slug}}.taskapp.celery.CeleryAppConfig'] +INSTALLED_APPS += ["{{cookiecutter.project_slug}}.taskapp.celery.CeleryAppConfig"] if USE_TZ: # http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-timezone CELERY_TIMEZONE = TIME_ZONE # http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-broker_url -CELERY_BROKER_URL = env('CELERY_BROKER_URL') +CELERY_BROKER_URL = env("CELERY_BROKER_URL") # http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-result_backend CELERY_RESULT_BACKEND = CELERY_BROKER_URL # http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-accept_content -CELERY_ACCEPT_CONTENT = ['json'] +CELERY_ACCEPT_CONTENT = ["json"] # http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-task_serializer -CELERY_TASK_SERIALIZER = 'json' +CELERY_TASK_SERIALIZER = "json" # http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-result_serializer -CELERY_RESULT_SERIALIZER = 'json' +CELERY_RESULT_SERIALIZER = "json" # http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-time-limit # TODO: set to whatever value is adequate in your circumstances CELERYD_TASK_TIME_LIMIT = 5 * 60 @@ -263,24 +251,24 @@ CELERYD_TASK_SOFT_TIME_LIMIT = 60 {%- endif %} # django-allauth # ------------------------------------------------------------------------------ -ACCOUNT_ALLOW_REGISTRATION = env.bool('DJANGO_ACCOUNT_ALLOW_REGISTRATION', True) +ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", True) # https://django-allauth.readthedocs.io/en/latest/configuration.html -ACCOUNT_AUTHENTICATION_METHOD = 'username' +ACCOUNT_AUTHENTICATION_METHOD = "username" # https://django-allauth.readthedocs.io/en/latest/configuration.html ACCOUNT_EMAIL_REQUIRED = True # https://django-allauth.readthedocs.io/en/latest/configuration.html -ACCOUNT_EMAIL_VERIFICATION = 'mandatory' +ACCOUNT_EMAIL_VERIFICATION = "mandatory" # https://django-allauth.readthedocs.io/en/latest/configuration.html -ACCOUNT_ADAPTER = '{{cookiecutter.project_slug}}.users.adapters.AccountAdapter' +ACCOUNT_ADAPTER = "{{cookiecutter.project_slug}}.users.adapters.AccountAdapter" # https://django-allauth.readthedocs.io/en/latest/configuration.html -SOCIALACCOUNT_ADAPTER = '{{cookiecutter.project_slug}}.users.adapters.SocialAccountAdapter' +SOCIALACCOUNT_ADAPTER = "{{cookiecutter.project_slug}}.users.adapters.SocialAccountAdapter" {% if cookiecutter.use_compressor == 'y' -%} # django-compressor # ------------------------------------------------------------------------------ # https://django-compressor.readthedocs.io/en/latest/quickstart/#installation -INSTALLED_APPS += ['compressor'] -STATICFILES_FINDERS += ['compressor.finders.CompressorFinder'] +INSTALLED_APPS += ["compressor"] +STATICFILES_FINDERS += ["compressor.finders.CompressorFinder"] {%- endif %} # Your stuff... diff --git a/{{cookiecutter.project_slug}}/config/settings/local.py b/{{cookiecutter.project_slug}}/config/settings/local.py index 6667a265..0c0588bd 100644 --- a/{{cookiecutter.project_slug}}/config/settings/local.py +++ b/{{cookiecutter.project_slug}}/config/settings/local.py @@ -6,42 +6,43 @@ from .base import env # https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = True # https://docs.djangoproject.com/en/dev/ref/settings/#secret-key -SECRET_KEY = env('DJANGO_SECRET_KEY', default='!!!SET DJANGO_SECRET_KEY!!!') +SECRET_KEY = env( + "DJANGO_SECRET_KEY", + default="!!!SET DJANGO_SECRET_KEY!!!", +) # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = [ - "localhost", - "0.0.0.0", - "127.0.0.1", -] +ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"] # CACHES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#caches CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', - 'LOCATION': '' + "default": { + "BACKEND": "django.core.cache.backends.locmem.LocMemCache", + "LOCATION": "", } } # TEMPLATES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#templates -TEMPLATES[0]['OPTIONS']['debug'] = DEBUG # noqa F405 +TEMPLATES[0]["OPTIONS"]["debug"] = DEBUG # noqa F405 # EMAIL # ------------------------------------------------------------------------------ {% if cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'y' -%} # https://docs.djangoproject.com/en/dev/ref/settings/#email-host -EMAIL_HOST = env('EMAIL_HOST', default='mailhog') +EMAIL_HOST = env("EMAIL_HOST", default="mailhog") {%- elif cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'n' -%} # https://docs.djangoproject.com/en/dev/ref/settings/#email-host -EMAIL_HOST = 'localhost' +EMAIL_HOST = "localhost" {%- else -%} # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend -EMAIL_BACKEND = env('DJANGO_EMAIL_BACKEND', default='django.core.mail.backends.console.EmailBackend') +EMAIL_BACKEND = env( + "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend" +) # https://docs.djangoproject.com/en/dev/ref/settings/#email-host -EMAIL_HOST = 'localhost' +EMAIL_HOST = "localhost" {%- endif %} # https://docs.djangoproject.com/en/dev/ref/settings/#email-port EMAIL_PORT = 1025 @@ -49,29 +50,28 @@ EMAIL_PORT = 1025 # django-debug-toolbar # ------------------------------------------------------------------------------ # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites -INSTALLED_APPS += ['debug_toolbar'] # noqa F405 +INSTALLED_APPS += ["debug_toolbar"] # noqa F405 # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#middleware -MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware'] # noqa F405 +MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # noqa F405 # https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config DEBUG_TOOLBAR_CONFIG = { - 'DISABLE_PANELS': [ - 'debug_toolbar.panels.redirects.RedirectsPanel', - ], - 'SHOW_TEMPLATE_CONTEXT': True, + "DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"], + "SHOW_TEMPLATE_CONTEXT": True, } # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips -INTERNAL_IPS = ['127.0.0.1', '10.0.2.2'] +INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"] {% if cookiecutter.use_docker == 'y' -%} -if env('USE_DOCKER') == 'yes': +if env("USE_DOCKER") == "yes": import socket + hostname, _, ips = socket.gethostbyname_ex(socket.gethostname()) - INTERNAL_IPS += [ip[:-1] + '1' for ip in ips] + INTERNAL_IPS += [ip[:-1] + "1" for ip in ips] {%- endif %} # django-extensions # ------------------------------------------------------------------------------ # https://django-extensions.readthedocs.io/en/latest/installation_instructions.html#configuration -INSTALLED_APPS += ['django_extensions'] # noqa F405 +INSTALLED_APPS += ["django_extensions"] # noqa F405 {% if cookiecutter.use_celery == 'y' -%} # Celery diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index e77d4304..16158742 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -8,37 +8,37 @@ from .base import env # GENERAL # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#secret-key -SECRET_KEY = env('DJANGO_SECRET_KEY') +SECRET_KEY = env("DJANGO_SECRET_KEY") # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = env.list('DJANGO_ALLOWED_HOSTS', default=['{{ cookiecutter.domain_name }}']) +ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["{{ cookiecutter.domain_name }}"]) # DATABASES # ------------------------------------------------------------------------------ -DATABASES['default'] = env.db('DATABASE_URL') # noqa F405 -DATABASES['default']['ATOMIC_REQUESTS'] = True # noqa F405 -DATABASES['default']['CONN_MAX_AGE'] = env.int('CONN_MAX_AGE', default=60) # noqa F405 +DATABASES["default"] = env.db("DATABASE_URL") # noqa F405 +DATABASES["default"]["ATOMIC_REQUESTS"] = True # noqa F405 +DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa F405 # CACHES # ------------------------------------------------------------------------------ CACHES = { - 'default': { - 'BACKEND': 'django_redis.cache.RedisCache', - 'LOCATION': env('REDIS_URL'), - 'OPTIONS': { - 'CLIENT_CLASS': 'django_redis.client.DefaultClient', + "default": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": env("REDIS_URL"), + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", # Mimicing memcache behavior. # http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior - 'IGNORE_EXCEPTIONS': True, - } + "IGNORE_EXCEPTIONS": True, + }, } } # SECURITY # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header -SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') +SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") # https://docs.djangoproject.com/en/dev/ref/settings/#secure-ssl-redirect -SECURE_SSL_REDIRECT = env.bool('DJANGO_SECURE_SSL_REDIRECT', default=True) +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/#csrf-cookie-secure @@ -48,45 +48,49 @@ CSRF_COOKIE_SECURE = True # TODO: set this to 60 seconds first and then to 518400 once you prove the former works SECURE_HSTS_SECONDS = 60 # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains -SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool('DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS', default=True) +SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( + "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True +) # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload -SECURE_HSTS_PRELOAD = env.bool('DJANGO_SECURE_HSTS_PRELOAD', default=True) +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) +SECURE_CONTENT_TYPE_NOSNIFF = env.bool( + "DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True +) # STORAGES # ------------------------------------------------------------------------------ # https://django-storages.readthedocs.io/en/latest/#installation -INSTALLED_APPS += ['storages'] # noqa F405 +INSTALLED_APPS += ["storages"] # noqa F405 # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings -AWS_ACCESS_KEY_ID = env('DJANGO_AWS_ACCESS_KEY_ID') +AWS_ACCESS_KEY_ID = env("DJANGO_AWS_ACCESS_KEY_ID") # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings -AWS_SECRET_ACCESS_KEY = env('DJANGO_AWS_SECRET_ACCESS_KEY') +AWS_SECRET_ACCESS_KEY = env("DJANGO_AWS_SECRET_ACCESS_KEY") # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings -AWS_STORAGE_BUCKET_NAME = env('DJANGO_AWS_STORAGE_BUCKET_NAME') +AWS_STORAGE_BUCKET_NAME = env("DJANGO_AWS_STORAGE_BUCKET_NAME") # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_QUERYSTRING_AUTH = False # DO NOT change these unless you know what you're doing. _AWS_EXPIRY = 60 * 60 * 24 * 7 # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_S3_OBJECT_PARAMETERS = { - 'CacheControl': f'max-age={_AWS_EXPIRY}, s-maxage={_AWS_EXPIRY}, must-revalidate', + "CacheControl": f"max-age={_AWS_EXPIRY}, s-maxage={_AWS_EXPIRY}, must-revalidate" } # STATIC # ------------------------ {% if cookiecutter.use_whitenoise == 'y' -%} -STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' +STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" {%- else %} -STATICFILES_STORAGE = 'config.settings.production.StaticRootS3Boto3Storage' -STATIC_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/' +STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage" +STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/" {%- endif %} # MEDIA # ------------------------------------------------------------------------------ {% if cookiecutter.use_whitenoise == 'y' -%} -DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' -MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/' +DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" +MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/" {%- else %} # region http://stackoverflow.com/questions/10390244/ # Full-fledge class: https://stackoverflow.com/a/18046120/104731 @@ -94,78 +98,79 @@ from storages.backends.s3boto3 import S3Boto3Storage # noqa E402 class StaticRootS3Boto3Storage(S3Boto3Storage): - location = 'static' + location = "static" class MediaRootS3Boto3Storage(S3Boto3Storage): - location = 'media' + location = "media" file_overwrite = False # endregion -DEFAULT_FILE_STORAGE = 'config.settings.production.MediaRootS3Boto3Storage' -MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/' +DEFAULT_FILE_STORAGE = "config.settings.production.MediaRootS3Boto3Storage" +MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/" {%- endif %} # TEMPLATES # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#templates -TEMPLATES[0]['OPTIONS']['loaders'] = [ # noqa F405 +TEMPLATES[0]["OPTIONS"]["loaders"] = [ # noqa F405 ( - 'django.template.loaders.cached.Loader', + "django.template.loaders.cached.Loader", [ - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', - ] - ), + "django.template.loaders.filesystem.Loader", + "django.template.loaders.app_directories.Loader", + ], + ) ] # EMAIL # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email DEFAULT_FROM_EMAIL = env( - 'DJANGO_DEFAULT_FROM_EMAIL', - default='{{cookiecutter.project_name}} ' + "DJANGO_DEFAULT_FROM_EMAIL", default="{{cookiecutter.project_name}} " ) # https://docs.djangoproject.com/en/dev/ref/settings/#server-email -SERVER_EMAIL = env('DJANGO_SERVER_EMAIL', default=DEFAULT_FROM_EMAIL) +SERVER_EMAIL = env("DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL) # https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix -EMAIL_SUBJECT_PREFIX = env('DJANGO_EMAIL_SUBJECT_PREFIX', default='[{{cookiecutter.project_name}}]') +EMAIL_SUBJECT_PREFIX = env( + "DJANGO_EMAIL_SUBJECT_PREFIX", default="[{{cookiecutter.project_name}}]" +) # ADMIN # ------------------------------------------------------------------------------ # Django Admin URL regex. -ADMIN_URL = env('DJANGO_ADMIN_URL') +ADMIN_URL = env("DJANGO_ADMIN_URL") # Anymail (Mailgun) # ------------------------------------------------------------------------------ # https://anymail.readthedocs.io/en/stable/installation/#installing-anymail -INSTALLED_APPS += ['anymail'] # noqa F405 -EMAIL_BACKEND = 'anymail.backends.mailgun.EmailBackend' +INSTALLED_APPS += ["anymail"] # noqa F405 +EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend" # https://anymail.readthedocs.io/en/stable/installation/#anymail-settings-reference ANYMAIL = { - 'MAILGUN_API_KEY': env('MAILGUN_API_KEY'), - 'MAILGUN_SENDER_DOMAIN': env('MAILGUN_DOMAIN') + "MAILGUN_API_KEY": env("MAILGUN_API_KEY"), + "MAILGUN_SENDER_DOMAIN": env("MAILGUN_DOMAIN"), } # Gunicorn # ------------------------------------------------------------------------------ -INSTALLED_APPS += ['gunicorn'] # noqa F405 +INSTALLED_APPS += ["gunicorn"] # noqa F405 {% if cookiecutter.use_whitenoise == 'y' -%} # WhiteNoise # ------------------------------------------------------------------------------ # http://whitenoise.evans.io/en/latest/django.html#enable-whitenoise -MIDDLEWARE.insert(1, 'whitenoise.middleware.WhiteNoiseMiddleware') # noqa F405 +MIDDLEWARE.insert(1, "whitenoise.middleware.WhiteNoiseMiddleware") # noqa F405 {% endif %} {%- if cookiecutter.use_compressor == 'y' -%} # django-compressor # ------------------------------------------------------------------------------ # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_ENABLED -COMPRESS_ENABLED = env.bool('COMPRESS_ENABLED', default=True) +COMPRESS_ENABLED = env.bool("COMPRESS_ENABLED", default=True) # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE -COMPRESS_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' +COMPRESS_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL COMPRESS_URL = STATIC_URL @@ -174,7 +179,7 @@ COMPRESS_URL = STATIC_URL # Collectfast # ------------------------------------------------------------------------------ # https://github.com/antonagestam/collectfast#installation -INSTALLED_APPS = ['collectfast'] + INSTALLED_APPS # noqa F405 +INSTALLED_APPS = ["collectfast"] + INSTALLED_APPS # noqa F405 AWS_PRELOAD_METADATA = True {% endif %} @@ -182,64 +187,64 @@ AWS_PRELOAD_METADATA = True # raven # ------------------------------------------------------------------------------ # https://docs.sentry.io/clients/python/integrations/django/ -INSTALLED_APPS += ['raven.contrib.django.raven_compat'] # noqa F405 -MIDDLEWARE = ['raven.contrib.django.raven_compat.middleware.SentryResponseErrorIdMiddleware'] + MIDDLEWARE +INSTALLED_APPS += ["raven.contrib.django.raven_compat"] # noqa F405 +MIDDLEWARE = ["raven.contrib.django.raven_compat.middleware.SentryResponseErrorIdMiddleware"] + MIDDLEWARE # Sentry # ------------------------------------------------------------------------------ -SENTRY_DSN = env('SENTRY_DSN') -SENTRY_CLIENT = env('DJANGO_SENTRY_CLIENT', default='raven.contrib.django.raven_compat.DjangoClient') +SENTRY_DSN = env("SENTRY_DSN") +SENTRY_CLIENT = env("DJANGO_SENTRY_CLIENT", default="raven.contrib.django.raven_compat.DjangoClient") LOGGING = { - 'version': 1, - 'disable_existing_loggers': True, - 'root': { - 'level': 'WARNING', - 'handlers': ['sentry'], + "version": 1, + "disable_existing_loggers": True, + "root": { + "level": "WARNING", + "handlers": ["sentry"], }, - 'formatters': { - 'verbose': { - 'format': '%(levelname)s %(asctime)s %(module)s ' - '%(process)d %(thread)d %(message)s' - }, - }, - 'handlers': { - 'sentry': { - 'level': 'ERROR', - 'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler', - }, - 'console': { - 'level': 'DEBUG', - 'class': 'logging.StreamHandler', - 'formatter': 'verbose' + "formatters": { + "verbose": { + "format": "%(levelname)s %(asctime)s %(module)s " + "%(process)d %(thread)d %(message)s" } }, - 'loggers': { - 'django.db.backends': { - 'level': 'ERROR', - 'handlers': ['console'], - 'propagate': False, + "handlers": { + "sentry": { + "level": "ERROR", + "class": "raven.contrib.django.raven_compat.handlers.SentryHandler", }, - 'raven': { - 'level': 'DEBUG', - 'handlers': ['console'], - 'propagate': False, + "console": { + "level": "DEBUG", + "class": "logging.StreamHandler", + "formatter": "verbose", }, - 'sentry.errors': { - 'level': 'DEBUG', - 'handlers': ['console'], - 'propagate': False, + }, + "loggers": { + "django.db.backends": { + "level": "ERROR", + "handlers": ["console"], + "propagate": False, }, - 'django.security.DisallowedHost': { - 'level': 'ERROR', - 'handlers': ['console', 'sentry'], - 'propagate': False, + "raven": { + "level": "DEBUG", + "handlers": ["console"], + "propagate": False, + }, + "sentry.errors": { + "level": "DEBUG", + "handlers": ["console"], + "propagate": False, + }, + "django.security.DisallowedHost": { + "level": "ERROR", + "handlers": ["console", "sentry"], + "propagate": False, }, }, } -SENTRY_CELERY_LOGLEVEL = env.int('DJANGO_SENTRY_LOG_LEVEL', logging.INFO) +SENTRY_CELERY_LOGLEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO) RAVEN_CONFIG = { - 'dsn': SENTRY_DSN + "dsn": SENTRY_DSN } {%- else %} @@ -252,43 +257,39 @@ RAVEN_CONFIG = { # See https://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'filters': { - 'require_debug_false': { - '()': 'django.utils.log.RequireDebugFalse' + "version": 1, + "disable_existing_loggers": False, + "filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}}, + "formatters": { + "verbose": { + "format": "%(levelname)s %(asctime)s %(module)s " + "%(process)d %(thread)d %(message)s" } }, - 'formatters': { - 'verbose': { - 'format': '%(levelname)s %(asctime)s %(module)s ' - '%(process)d %(thread)d %(message)s' + "handlers": { + "mail_admins": { + "level": "ERROR", + "filters": ["require_debug_false"], + "class": "django.utils.log.AdminEmailHandler", + }, + "console": { + "level": "DEBUG", + "class": "logging.StreamHandler", + "formatter": "verbose", }, }, - 'handlers': { - 'mail_admins': { - 'level': 'ERROR', - 'filters': ['require_debug_false'], - 'class': 'django.utils.log.AdminEmailHandler' + "loggers": { + "django.request": { + "handlers": ["mail_admins"], + "level": "ERROR", + "propagate": True, }, - 'console': { - 'level': 'DEBUG', - 'class': 'logging.StreamHandler', - 'formatter': 'verbose', + "django.security.DisallowedHost": { + "level": "ERROR", + "handlers": ["console", "mail_admins"], + "propagate": True, }, }, - 'loggers': { - 'django.request': { - 'handlers': ['mail_admins'], - 'level': 'ERROR', - 'propagate': True - }, - 'django.security.DisallowedHost': { - 'level': 'ERROR', - 'handlers': ['console', 'mail_admins'], - 'propagate': True - } - } } {% endif %} diff --git a/{{cookiecutter.project_slug}}/config/settings/test.py b/{{cookiecutter.project_slug}}/config/settings/test.py index e947d410..2ade134a 100644 --- a/{{cookiecutter.project_slug}}/config/settings/test.py +++ b/{{cookiecutter.project_slug}}/config/settings/test.py @@ -10,7 +10,10 @@ from .base import env # https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = False # https://docs.djangoproject.com/en/dev/ref/settings/#secret-key -SECRET_KEY = env("DJANGO_SECRET_KEY", default="!!!SET DJANGO_SECRET_KEY!!!") +SECRET_KEY = env( + "DJANGO_SECRET_KEY", + default="!!!SET DJANGO_SECRET_KEY!!!", +) # https://docs.djangoproject.com/en/dev/ref/settings/#test-runner TEST_RUNNER = "django.test.runner.DiscoverRunner" @@ -19,7 +22,8 @@ TEST_RUNNER = "django.test.runner.DiscoverRunner" # https://docs.djangoproject.com/en/dev/ref/settings/#caches CACHES = { "default": { - "BACKEND": "django.core.cache.backends.locmem.LocMemCache", "LOCATION": "" + "BACKEND": "django.core.cache.backends.locmem.LocMemCache", + "LOCATION": "", } } diff --git a/{{cookiecutter.project_slug}}/config/urls.py b/{{cookiecutter.project_slug}}/config/urls.py index 62d86c94..909d5e86 100644 --- a/{{cookiecutter.project_slug}}/config/urls.py +++ b/{{cookiecutter.project_slug}}/config/urls.py @@ -8,22 +8,15 @@ from django.views import defaults as default_views urlpatterns = [ path("", TemplateView.as_view(template_name="pages/home.html"), name="home"), path( - "about/", - TemplateView.as_view(template_name="pages/about.html"), - name="about", + "about/", TemplateView.as_view(template_name="pages/about.html"), name="about" ), # Django Admin, use {% raw %}{% url 'admin:index' %}{% endraw %} path(settings.ADMIN_URL, admin.site.urls), # User management - path( - "users/", - include("{{ cookiecutter.project_slug }}.users.urls", namespace="users"), - ), + path("users/", include("{{ cookiecutter.project_slug }}.users.urls", namespace="users")), path("accounts/", include("allauth.urls")), # Your stuff: custom urls includes go here -] + static( - settings.MEDIA_URL, document_root=settings.MEDIA_ROOT -) +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) if settings.DEBUG: # This allows the error pages to be debugged during development, just visit diff --git a/{{cookiecutter.project_slug}}/config/wsgi.py b/{{cookiecutter.project_slug}}/config/wsgi.py index 4c135006..abc09314 100644 --- a/{{cookiecutter.project_slug}}/config/wsgi.py +++ b/{{cookiecutter.project_slug}}/config/wsgi.py @@ -20,11 +20,12 @@ from django.core.wsgi import get_wsgi_application # This allows easy placement of apps within the interior # {{ cookiecutter.project_slug }} directory. -app_path = os.path.abspath(os.path.join( - os.path.dirname(os.path.abspath(__file__)), os.pardir)) -sys.path.append(os.path.join(app_path, '{{ cookiecutter.project_slug }}')) +app_path = os.path.abspath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) +) +sys.path.append(os.path.join(app_path, "{{ cookiecutter.project_slug }}")) {% if cookiecutter.use_sentry == 'y' -%} -if os.environ.get('DJANGO_SETTINGS_MODULE') == 'config.settings.production': +if os.environ.get("DJANGO_SETTINGS_MODULE") == "config.settings.production": from raven.contrib.django.raven_compat.middleware.wsgi import Sentry {%- endif %} # We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks @@ -38,7 +39,7 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production") # setting points here. application = get_wsgi_application() {% if cookiecutter.use_sentry == 'y' -%} -if os.environ.get('DJANGO_SETTINGS_MODULE') == 'config.settings.production': +if os.environ.get("DJANGO_SETTINGS_MODULE") == "config.settings.production": application = Sentry(application) {%- endif %} # Apply WSGI middleware here. diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index a496135b..c9fbb96e 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -19,6 +19,7 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar # ------------------------------------------------------------------------------ flake8==3.7.5 # https://github.com/PyCQA/flake8 coverage==4.5.2 # https://github.com/nedbat/coveragepy +black==18.9b0 # https://github.com/ambv/black # Django # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/celery.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/celery.py index 570abc12..b3b086a0 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/celery.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/celery.py @@ -1,4 +1,4 @@ -{% if cookiecutter.use_celery == 'y' %} +{% if cookiecutter.use_celery == 'y' -%} import os from celery import Celery from django.apps import apps, AppConfig @@ -7,26 +7,28 @@ from django.conf import settings if not settings.configured: # set the default Django settings module for the 'celery' program. - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.local') # pragma: no cover + os.environ.setdefault( + "DJANGO_SETTINGS_MODULE", "config.settings.local" + ) # pragma: no cover -app = Celery('{{cookiecutter.project_slug}}') +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') +app.config_from_object("django.conf:settings", namespace="CELERY") class CeleryAppConfig(AppConfig): - name = '{{cookiecutter.project_slug}}.taskapp' - verbose_name = 'Celery Config' + name = "{{cookiecutter.project_slug}}.taskapp" + verbose_name = "Celery Config" def ready(self): installed_apps = [app_config.name for app_config in apps.get_app_configs()] app.autodiscover_tasks(lambda: installed_apps, force=True) + {%- if cookiecutter.use_sentry == 'y' %} - {% if cookiecutter.use_sentry == 'y' -%} if hasattr(settings, 'RAVEN_CONFIG'): # Celery signal registration {% if cookiecutter.use_pycharm == 'y' -%} @@ -51,7 +53,7 @@ class CeleryAppConfig(AppConfig): @app.task(bind=True) def debug_task(self): - print(f'Request: {self.request!r}') # pragma: no cover + print(f"Request: {self.request!r}") # pragma: no cover {% else %} # Use this as a starting point for your project with celery. # If you are not using celery, you can remove this app diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py index 9361d6ec..0d206fae 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py @@ -7,12 +7,10 @@ from django.http import HttpRequest class AccountAdapter(DefaultAccountAdapter): - def is_open_for_signup(self, request: HttpRequest): return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True) class SocialAccountAdapter(DefaultSocialAccountAdapter): - def is_open_for_signup(self, request: HttpRequest, sociallogin: Any): return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py index 7bba81ff..250cc904 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py @@ -6,7 +6,6 @@ User = get_user_model() class UserChangeForm(forms.UserChangeForm): - class Meta(forms.UserChangeForm.Meta): model = User diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py index 00990576..b5371366 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py @@ -19,9 +19,7 @@ class UserFactory(DjangoModelFactory): digits=True, upper_case=True, lower_case=True, - ).generate( - extra_kwargs={} - ) + ).generate(extra_kwargs={}) self.set_password(password) class Meta: diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py index e8066164..dfa5da52 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py @@ -7,7 +7,6 @@ pytestmark = pytest.mark.django_db class TestUserCreationForm: - def test_clean_username(self): # A user with proto_user params does not exist yet. proto_user = UserFactory.build() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py index 0992e462..76cb80aa 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py @@ -40,7 +40,6 @@ class TestUserUpdateView: class TestUserRedirectView: - def test_get_redirect_url( self, user: settings.AUTH_USER_MODEL, request_factory: RequestFactory ): From 3bd7aa4e1a14763579824cbdf99e83eab9139466 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 18 Mar 2019 20:55:47 +0000 Subject: [PATCH 025/126] Fix build error with windows=y and docker=y combination Fixes #1917 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index e43b70af..b73e4602 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -2,7 +2,7 @@ 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 +rcssmin==1.0.6{% if cookiecutter.windows == 'y' and use_docker == 'n' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin {%- endif %} argon2-cffi==19.1.0 # https://github.com/hynek/argon2_cffi {%- if cookiecutter.use_whitenoise == 'y' %} From b312d516a422b08c299b57cdd3515a235f82b03e Mon Sep 17 00:00:00 2001 From: Demetris Date: Tue, 19 Mar 2019 11:32:45 +0200 Subject: [PATCH 026/126] Replace Caddy with Traefik (#1714) ## Description Replace Caddy with Traefik ## Rationale There is some trouble with the Caddy license (https://github.com/pydanny/cookiecutter-django/pull/1282#issuecomment-329617536) @drdaeman suggested using Traefik (https://github.com/pydanny/cookiecutter-django/pull/1282#issuecomment-353655273) which supports ACME and also plays very nice with Docker. ## Comments I am currently using the proposed setup on a live site and it working great so far. If this PR is of interest to the maintainers, then I could commit more changes and take care of the documentation. Of course, any suggestions by the more experienced people around here, are welcome! --- CONTRIBUTORS.rst | 2 + README.rst | 4 +- docs/deployment-with-docker.rst | 10 ++--- docs/developing-locally-docker.rst | 3 +- .../.envs/.production/.caddy | 3 -- .../compose/production/caddy/Caddyfile | 15 ------- .../compose/production/caddy/Dockerfile | 3 -- .../compose/production/traefik/Dockerfile | 5 +++ .../compose/production/traefik/traefik.toml | 41 +++++++++++++++++++ .../merge_production_dotenvs_in_dotenv.py | 1 - {{cookiecutter.project_slug}}/production.yml | 12 +++--- 11 files changed, 61 insertions(+), 38 deletions(-) delete mode 100644 {{cookiecutter.project_slug}}/.envs/.production/.caddy delete mode 100644 {{cookiecutter.project_slug}}/compose/production/caddy/Caddyfile delete mode 100644 {{cookiecutter.project_slug}}/compose/production/caddy/Dockerfile create mode 100644 {{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile create mode 100644 {{cookiecutter.project_slug}}/compose/production/traefik/traefik.toml diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index dc41463f..d8d312ab 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -93,6 +93,7 @@ Listed in alphabetical order. Davit Tovmasyan `@davitovmasyan`_ Davur Clementsen `@dsclementsen`_ @davur Delio Castillo `@jangeador`_ @jangeador + Demetris Stavrou `@demestav`_ Denis Orehovsky `@apirobot`_ Dónal Adams `@epileptic-fish`_ Diane Chen `@purplediane`_ @purplediane88 @@ -216,6 +217,7 @@ Listed in alphabetical order. .. _@Collederas: https://github.com/Collederas .. _@davitovmasyan: https://github.com/davitovmasyan .. _@ddiazpinto: https://github.com/ddiazpinto +.. _@demestav: https://github.com/demestav .. _@dezoito: https://github.com/dezoito .. _@dhepper: https://github.com/dhepper .. _@dot2dotseurat: https://github.com/dot2dotseurat diff --git a/README.rst b/README.rst index 37f36204..2c037e51 100644 --- a/README.rst +++ b/README.rst @@ -48,7 +48,7 @@ Features * Optional custom static build using Gulp and livereload * Send emails via Anymail_ (using Mailgun_ by default, but switchable) * Media storage using Amazon S3 -* Docker support using docker-compose_ for development and production (using Caddy_ with LetsEncrypt_ support) +* Docker support using docker-compose_ for development and production (using Traefik_ with LetsEncrypt_ support) * Procfile_ for deploying to Heroku * Instructions for deploying to PythonAnywhere_ * Run tests with unittest or py.test @@ -82,7 +82,7 @@ Optional Integrations .. _Sentry: https://sentry.io/welcome/ .. _docker-compose: https://github.com/docker/compose .. _PythonAnywhere: https://www.pythonanywhere.com/ -.. _Caddy: https://caddyserver.com/ +.. _Traefik: https://traefik.io/ .. _LetsEncrypt: https://letsencrypt.org/ Constraints diff --git a/docs/deployment-with-docker.rst b/docs/deployment-with-docker.rst index f6e21e82..904947e3 100644 --- a/docs/deployment-with-docker.rst +++ b/docs/deployment-with-docker.rst @@ -19,7 +19,7 @@ Before you begin, check out the ``production.yml`` file in the root of this proj * ``django``: your application running behind ``Gunicorn``; * ``postgres``: PostgreSQL database with the application's relational data; * ``redis``: Redis instance for caching; -* ``caddy``: Caddy web server with HTTPS on by default. +* ``traefik``: Traefik reverse proxy with HTTPS on by default. Provided you have opted for Celery (via setting ``use_celery`` to ``y``) there are three more services: @@ -63,11 +63,11 @@ It is always better to deploy a site behind HTTPS and will become crucial as the * Access to the Django admin is set up by default to require HTTPS in production or once *live*. -The Caddy web server used in the default configuration will get you a valid certificate from Lets Encrypt and update it automatically. All you need to do to enable this is to make sure that your DNS records are pointing to the server Caddy runs on. +The Traefik reverse proxy used in the default configuration will get you a valid certificate from Lets Encrypt and update it automatically. All you need to do to enable this is to make sure that your DNS records are pointing to the server Traefik runs on. -You can read more about this here at `Automatic HTTPS`_ in the Caddy docs. +You can read more about this feature and how to configure it, at `Automatic HTTPS`_ in the Traefik docs. -.. _Automatic HTTPS: https://caddyserver.com/docs/automatic-https +.. _Automatic HTTPS: https://docs.traefik.io/configuration/acme/ (Optional) Postgres Data Volume Modifications @@ -112,7 +112,7 @@ If you want to scale your application, run:: docker-compose -f production.yml scale django=4 docker-compose -f production.yml scale celeryworker=2 -.. warning:: don't try to scale ``postgres``, ``celerybeat``, or ``caddy``. +.. warning:: don't try to scale ``postgres``, ``celerybeat``, or ``traefik``. To see how your containers are doing run:: diff --git a/docs/developing-locally-docker.rst b/docs/developing-locally-docker.rst index 895140f9..10815419 100644 --- a/docs/developing-locally-docker.rst +++ b/docs/developing-locally-docker.rst @@ -105,7 +105,6 @@ The most important thing for us here now is ``env_file`` section enlisting ``./. │   ├── .django │   └── .postgres └── .production - ├── .caddy ├── .django └── .postgres @@ -120,7 +119,7 @@ Consider the aforementioned ``.envs/.local/.postgres``: :: POSTGRES_USER=XgOWtQtJecsAbaIyslwGvFvPawftNaqO POSTGRES_PASSWORD=jSljDz4whHuwO3aJIgVBrqEml5Ycbghorep4uVJ4xjDYQu0LfuTZdctj7y0YcCLu -The three envs we are presented with here are ``POSTGRES_DB``, ``POSTGRES_USER``, and ``POSTGRES_PASSWORD`` (by the way, their values have also been generated for you). You might have figured out already where these definitions will end up; it's all the same with ``django`` and ``caddy`` service container envs. +The three envs we are presented with here are ``POSTGRES_DB``, ``POSTGRES_USER``, and ``POSTGRES_PASSWORD`` (by the way, their values have also been generated for you). You might have figured out already where these definitions will end up; it's all the same with ``django`` service container envs. One final touch: should you ever need to merge ``.envs/production/*`` in a single ``.env`` run the ``merge_production_dotenvs_in_dotenv.py``: :: diff --git a/{{cookiecutter.project_slug}}/.envs/.production/.caddy b/{{cookiecutter.project_slug}}/.envs/.production/.caddy deleted file mode 100644 index 83d7fc7a..00000000 --- a/{{cookiecutter.project_slug}}/.envs/.production/.caddy +++ /dev/null @@ -1,3 +0,0 @@ -# Caddy -# ------------------------------------------------------------------------------ -DOMAIN_NAME={{ cookiecutter.domain_name }} diff --git a/{{cookiecutter.project_slug}}/compose/production/caddy/Caddyfile b/{{cookiecutter.project_slug}}/compose/production/caddy/Caddyfile deleted file mode 100644 index 323e4392..00000000 --- a/{{cookiecutter.project_slug}}/compose/production/caddy/Caddyfile +++ /dev/null @@ -1,15 +0,0 @@ -www.{% raw %}{$DOMAIN_NAME}{% endraw %} { - redir https://{% raw %}{$DOMAIN_NAME}{% endraw %} -} - -{% raw %}{$DOMAIN_NAME}{% endraw %} { - proxy / django:5000 { - 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 - gzip -} diff --git a/{{cookiecutter.project_slug}}/compose/production/caddy/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/caddy/Dockerfile deleted file mode 100644 index c32efb3e..00000000 --- a/{{cookiecutter.project_slug}}/compose/production/caddy/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM abiosoft/caddy:0.11.0 - -COPY ./compose/production/caddy/Caddyfile /etc/Caddyfile diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile new file mode 100644 index 00000000..7088e6fe --- /dev/null +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile @@ -0,0 +1,5 @@ +FROM traefik:alpine +RUN mkdir -p /etc/traefik/acme +RUN touch /etc/traefik/acme/acme.json +RUN chmod 600 /etc/traefik/acme/acme.json +COPY ./compose/production/traefik/traefik.toml /etc/traefik diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.toml b/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.toml new file mode 100644 index 00000000..ad1f20e9 --- /dev/null +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.toml @@ -0,0 +1,41 @@ +logLevel = "INFO" +defaultEntryPoints = ["http", "https"] + +# Entrypoints, http and https +[entryPoints] + # http should be redirected to https + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + # https is the default + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + +# Enable ACME (Let's Encrypt): automatic SSL +[acme] +# Email address used for registration +email = "{{ cookiecutter.email }}" +storageFile = "/etc/traefik/acme/acme.json" +entryPoint = "https" +onDemand = false +OnHostRule = true + # Use a HTTP-01 acme challenge rather than TLS-SNI-01 challenge + [acme.httpChallenge] + entryPoint = "http" + +[file] +[backends] + [backends.django] + [backends.django.servers.server1] + url = "http://django:5000" + +[frontends] + [frontends.django] + backend = "django" + passHostHeader = true + [frontends.django.headers] + HostsProxyHeaders = ['X-CSRFToken'] + [frontends.django.routes.dr1] + rule = "Host:{{ cookiecutter.domain_name }}" diff --git a/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py b/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py index 5c3027a4..4e70e2ad 100644 --- a/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py +++ b/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py @@ -8,7 +8,6 @@ PRODUCTION_DOTENVS_DIR_PATH = os.path.join(ROOT_DIR_PATH, ".envs", ".production" PRODUCTION_DOTENV_FILE_PATHS = [ os.path.join(PRODUCTION_DOTENVS_DIR_PATH, ".django"), os.path.join(PRODUCTION_DOTENVS_DIR_PATH, ".postgres"), - os.path.join(PRODUCTION_DOTENVS_DIR_PATH, ".caddy"), ] DOTENV_FILE_PATH = os.path.join(ROOT_DIR_PATH, ".env") diff --git a/{{cookiecutter.project_slug}}/production.yml b/{{cookiecutter.project_slug}}/production.yml index fd8388ac..88cf8773 100644 --- a/{{cookiecutter.project_slug}}/production.yml +++ b/{{cookiecutter.project_slug}}/production.yml @@ -3,7 +3,7 @@ version: '3' volumes: production_postgres_data: {} production_postgres_data_backups: {} - production_caddy: {} + production_traefik: {} services: django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %} @@ -30,17 +30,15 @@ services: env_file: - ./.envs/.production/.postgres - caddy: + traefik: build: context: . - dockerfile: ./compose/production/caddy/Dockerfile - image: {{ cookiecutter.project_slug }}_production_caddy + dockerfile: ./compose/production/traefik/Dockerfile + image: {{ cookiecutter.project_slug }}_production_traefik depends_on: - django volumes: - - production_caddy:/root/.caddy - env_file: - - ./.envs/.production/.caddy + - production_traefik:/etc/traefik/acme ports: - "0.0.0.0:80:80" - "0.0.0.0:443:443" From e740a54da68b383d79ef33225d5c8ca5081eeced Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 19 Mar 2019 12:30:19 +0000 Subject: [PATCH 027/126] Update Flower version --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index b73e4602..79999cb4 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -12,7 +12,7 @@ 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 {%- if cookiecutter.use_docker == 'y' %} -flower==0.9.2 # https://github.com/mher/flower +flower==0.9.3 # https://github.com/mher/flower {%- endif %} {%- endif %} From 6e9f87fced04ab76a133ae2fbd9b0bbbe52bd61f Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 19 Mar 2019 19:57:31 +0000 Subject: [PATCH 028/126] Set AWS_DEFAULT_ACL to None as per django-storages documentation fixes #1885 --- {{cookiecutter.project_slug}}/config/settings/production.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 16158742..19195582 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -76,6 +76,8 @@ _AWS_EXPIRY = 60 * 60 * 24 * 7 AWS_S3_OBJECT_PARAMETERS = { "CacheControl": f"max-age={_AWS_EXPIRY}, s-maxage={_AWS_EXPIRY}, must-revalidate" } +# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings +AWS_DEFAULT_ACL = None # STATIC # ------------------------ From b594a1584718775e4e8abd928a68213b899719f4 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 19 Mar 2019 20:02:26 +0000 Subject: [PATCH 029/126] Add code style black to the generated README --- {{cookiecutter.project_slug}}/README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/{{cookiecutter.project_slug}}/README.rst b/{{cookiecutter.project_slug}}/README.rst index 49df7019..6ef3b63c 100644 --- a/{{cookiecutter.project_slug}}/README.rst +++ b/{{cookiecutter.project_slug}}/README.rst @@ -6,6 +6,9 @@ .. image:: https://img.shields.io/badge/built%20with-Cookiecutter%20Django-ff69b4.svg :target: https://github.com/pydanny/cookiecutter-django/ :alt: Built with Cookiecutter Django +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + :alt: Black code style {% if cookiecutter.open_source_license != "Not open source" %} :License: {{cookiecutter.open_source_license}} From 7d1e90bdf5343299c31388981b6af7cb0e631bbb Mon Sep 17 00:00:00 2001 From: Guilherme Fabrizio Date: Wed, 20 Mar 2019 10:04:44 +0000 Subject: [PATCH 030/126] Migrate to unified Sentry SDK (#1820) The raven library is deprecated. Replace it by the new sentry-sdk library: https://docs.sentry.io/error-reporting/quickstart/?platform=python fixes #1818 --- docs/settings.rst | 1 - .../config/settings/production.py | 132 ++++++++---------- {{cookiecutter.project_slug}}/config/wsgi.py | 8 -- .../requirements/production.txt | 4 +- .../taskapp/celery.py | 22 --- 5 files changed, 64 insertions(+), 103 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index 26b161a0..705add87 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -45,7 +45,6 @@ DJANGO_AWS_ACCESS_KEY_ID AWS_ACCESS_KEY_ID n/a 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 SENTRY_DSN SENTRY_DSN n/a raises error -DJANGO_SENTRY_CLIENT SENTRY_CLIENT n/a raven.contrib.django.raven_compat.DjangoClient 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 diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 19195582..546f2364 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -1,6 +1,14 @@ {% if cookiecutter.use_sentry == 'y' -%} import logging +import sentry_sdk + +from sentry_sdk.integrations.django import DjangoIntegration +from sentry_sdk.integrations.logging import LoggingIntegration +{%- if cookiecutter.use_celery == 'y' %} +from sentry_sdk.integrations.celery import CeleryIntegration +{% endif %} + {% endif -%} from .base import * # noqa from .base import env @@ -175,7 +183,6 @@ COMPRESS_ENABLED = env.bool("COMPRESS_ENABLED", default=True) COMPRESS_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL COMPRESS_URL = STATIC_URL - {% endif %} {%- if cookiecutter.use_whitenoise == 'n' -%} # Collectfast @@ -183,81 +190,16 @@ COMPRESS_URL = STATIC_URL # https://github.com/antonagestam/collectfast#installation INSTALLED_APPS = ["collectfast"] + INSTALLED_APPS # noqa F405 AWS_PRELOAD_METADATA = True - {% endif %} -{%- if cookiecutter.use_sentry == 'y' -%} -# raven -# ------------------------------------------------------------------------------ -# https://docs.sentry.io/clients/python/integrations/django/ -INSTALLED_APPS += ["raven.contrib.django.raven_compat"] # noqa F405 -MIDDLEWARE = ["raven.contrib.django.raven_compat.middleware.SentryResponseErrorIdMiddleware"] + MIDDLEWARE - -# Sentry -# ------------------------------------------------------------------------------ -SENTRY_DSN = env("SENTRY_DSN") -SENTRY_CLIENT = env("DJANGO_SENTRY_CLIENT", default="raven.contrib.django.raven_compat.DjangoClient") -LOGGING = { - "version": 1, - "disable_existing_loggers": True, - "root": { - "level": "WARNING", - "handlers": ["sentry"], - }, - "formatters": { - "verbose": { - "format": "%(levelname)s %(asctime)s %(module)s " - "%(process)d %(thread)d %(message)s" - } - }, - "handlers": { - "sentry": { - "level": "ERROR", - "class": "raven.contrib.django.raven_compat.handlers.SentryHandler", - }, - "console": { - "level": "DEBUG", - "class": "logging.StreamHandler", - "formatter": "verbose", - }, - }, - "loggers": { - "django.db.backends": { - "level": "ERROR", - "handlers": ["console"], - "propagate": False, - }, - "raven": { - "level": "DEBUG", - "handlers": ["console"], - "propagate": False, - }, - "sentry.errors": { - "level": "DEBUG", - "handlers": ["console"], - "propagate": False, - }, - "django.security.DisallowedHost": { - "level": "ERROR", - "handlers": ["console", "sentry"], - "propagate": False, - }, - }, -} - -SENTRY_CELERY_LOGLEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO) -RAVEN_CONFIG = { - "dsn": SENTRY_DSN -} - -{%- else %} # LOGGING # ------------------------------------------------------------------------------ -# See: https://docs.djangoproject.com/en/dev/ref/settings/#logging +# https://docs.djangoproject.com/en/dev/ref/settings/#logging +# See https://docs.djangoproject.com/en/dev/topics/logging for +# more details on how to customize your logging configuration. +{% if cookiecutter.use_sentry == 'n' -%} # A sample logging configuration. The only tangible logging # performed by this configuration is to send an email to # the site admins on every HTTP 500 error when DEBUG=False. -# See https://docs.djangoproject.com/en/dev/topics/logging for -# more details on how to customize your logging configuration. LOGGING = { "version": 1, "disable_existing_loggers": False, @@ -293,7 +235,57 @@ LOGGING = { }, }, } +{% else %} +LOGGING = { + "version": 1, + "disable_existing_loggers": True, + "formatters": { + "verbose": { + "format": "%(levelname)s %(asctime)s %(module)s " + "%(process)d %(thread)d %(message)s" + } + }, + "handlers": { + "console": { + "level": "DEBUG", + "class": "logging.StreamHandler", + "formatter": "verbose", + } + }, + "loggers": { + "django.db.backends": { + "level": "ERROR", + "handlers": ["console"], + "propagate": False, + }, + # Errors logged by the SDK itself + "sentry_sdk": {"level": "ERROR", "handlers": ["console"], "propagate": False}, + "django.security.DisallowedHost": { + "level": "ERROR", + "handlers": ["console"], + "propagate": False, + }, + }, +} +# Sentry +# ------------------------------------------------------------------------------ +SENTRY_DSN = env("SENTRY_DSN") +SENTRY_LOG_LEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO) + +sentry_logging = LoggingIntegration( + level=SENTRY_LOG_LEVEL, # Capture info and above as breadcrumbs + event_level=None, # Send no events from log messages +) + +{%- if cookiecutter.use_celery == 'y' %} +sentry_sdk.init( + dsn=SENTRY_DSN, + integrations=[sentry_logging, DjangoIntegration(), CeleryIntegration()], +) +{% else %} +sentry_sdk.init(dsn=SENTRY_DSN, integrations=[sentry_logging, DjangoIntegration()]) +{% endif -%} {% endif %} # Your stuff... # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/config/wsgi.py b/{{cookiecutter.project_slug}}/config/wsgi.py index abc09314..1899a30c 100644 --- a/{{cookiecutter.project_slug}}/config/wsgi.py +++ b/{{cookiecutter.project_slug}}/config/wsgi.py @@ -24,10 +24,6 @@ app_path = os.path.abspath( os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) ) sys.path.append(os.path.join(app_path, "{{ cookiecutter.project_slug }}")) -{% if cookiecutter.use_sentry == 'y' -%} -if os.environ.get("DJANGO_SETTINGS_MODULE") == "config.settings.production": - from raven.contrib.django.raven_compat.middleware.wsgi import Sentry -{%- endif %} # We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks # if running multiple sites in the same mod_wsgi process. To fix this, use # mod_wsgi daemon mode with each site in its own daemon process, or use @@ -38,10 +34,6 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production") # file. This includes Django's development server, if the WSGI_APPLICATION # setting points here. application = get_wsgi_application() -{% if cookiecutter.use_sentry == 'y' -%} -if os.environ.get("DJANGO_SETTINGS_MODULE") == "config.settings.production": - application = Sentry(application) -{%- endif %} # Apply WSGI middleware here. # from helloworld.wsgi import HelloWorldApplication # application = HelloWorldApplication(application) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 34877e3f..628a67bd 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,10 +8,10 @@ psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 Collectfast==0.6.2 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -raven==6.10.0 # https://github.com/getsentry/raven-python +sentry-sdk==0.7.6 # https://github.com/getsentry/sentry-python {%- endif %} # Django # ------------------------------------------------------------------------------ django-storages[boto3]==1.7.1 # https://github.com/jschneier/django-storages -django-anymail[mailgun]==5.0 # https://github.com/anymail/django-anymail \ No newline at end of file +django-anymail[mailgun]==5.0 # https://github.com/anymail/django-anymail diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/celery.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/celery.py index b3b086a0..529da1ae 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/celery.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/celery.py @@ -27,28 +27,6 @@ class CeleryAppConfig(AppConfig): def ready(self): installed_apps = [app_config.name for app_config in apps.get_app_configs()] app.autodiscover_tasks(lambda: installed_apps, force=True) - {%- if cookiecutter.use_sentry == 'y' %} - - if hasattr(settings, 'RAVEN_CONFIG'): - # Celery signal registration -{% if cookiecutter.use_pycharm == 'y' -%} - # Since raven is required in production only, - # imports might (most surely will) be wiped out - # during PyCharm code clean up started - # in other environments. - # @formatter:off -{%- endif %} - from raven import Client as RavenClient - from raven.contrib.celery import register_signal as raven_register_signal - from raven.contrib.celery import register_logger_signal as raven_register_logger_signal -{% if cookiecutter.use_pycharm == 'y' -%} - # @formatter:on -{%- endif %} - - raven_client = RavenClient(dsn=settings.RAVEN_CONFIG['dsn']) - raven_register_logger_signal(raven_client) - raven_register_signal(raven_client) - {%- endif %} @app.task(bind=True) From 5bf0a397ac2fef207b817cff99f08373841b7eb9 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Wed, 20 Mar 2019 12:09:43 +0000 Subject: [PATCH 031/126] Pin redis version --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 6f9cd64f..cbc9485f 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -8,7 +8,7 @@ argon2-cffi==19.1.0 # https://github.com/hynek/argon2_cffi {%- if cookiecutter.use_whitenoise == 'y' %} whitenoise==4.1.2 # https://github.com/evansd/whitenoise {%- endif %} -redis>=3.2.0 # https://github.com/antirez/redis +redis==3.2.1 # https://github.com/antirez/redis {%- if cookiecutter.use_celery == "y" %} celery==4.2.1 # pyup: < 5.0 # https://github.com/celery/celery kombu==4.4.0 # https://github.com/celery/kombu From f1def67b6d70dd8ef31d8e38bbf9faaa0db8f483 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Wed, 20 Mar 2019 12:12:32 +0000 Subject: [PATCH 032/126] Fix broken links in list of contributors --- CONTRIBUTORS.rst | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index d804a970..b7607562 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -46,7 +46,7 @@ Listed in alphabetical order. Aaron Eikenberry `@aeikenberry`_ Adam Bogdał `@bogdal`_ Adam Dobrawy `@ad-m`_ - Adam Steele `@adammsteele` + Adam Steele `@adammsteele`_ Agam Dua Alberto Sanchez `@alb3rto`_ Alex Tsai `@caffodian`_ @@ -64,14 +64,14 @@ Listed in alphabetical order. Areski Belaid `@areski`_ Ashley Camba Barclay Gauld `@yunti`_ - Ben Warren `@bwarren2` + Ben Warren `@bwarren2`_ Ben Lopatin Benjamin Abel Bert de Miranda `@bertdemiranda`_ Bo Lopker `@blopker`_ Bouke Haarsma Brent Payne `@brentpayne`_ @brentpayne - Bartek `@btknu` + Bartek `@btknu`_ Burhan Khalid            `@burhan`_                   @burhan Carl Johnson `@carlmjohnson`_ @carlmjohnson Catherine Devlin `@catherinedevlin`_ @@ -159,7 +159,7 @@ Listed in alphabetical order. Roman Afanaskin `@siauPatrick`_ Roman Osipenko `@romanosipenko`_ Russell Davies - Sascha `@saschalalala` @saschalalala + Sascha `@saschalalala`_ @saschalalala Sam Collins `@MightySCollins`_ Shupeyko Nikita `@webyneter`_ Sławek Ehlert `@slafs`_ @@ -304,6 +304,14 @@ Listed in alphabetical order. .. _@ahhda: https://github.com/ahhda .. _@keithjeb: https://github.com/keithjeb .. _@btknu: https://github.com/btknu +.. _@rolep: https://github.com/rolep +.. _@canonnervio: https://github.com/canonnervio +.. _@jcass77: https://github.com/jcass77 +.. _@Egregors: https://github.com/Egregors +.. _@saschalalala: https://github.com/saschalalala +.. _@mrcoles: https://github.com/mrcoles +.. _@ericgroom: https://github.com/ericgroom + Special Thanks ~~~~~~~~~~~~~~ From 823ee637d14fe163cf9c3563a9fc37a01497601a Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Wed, 20 Mar 2019 12:16:43 +0000 Subject: [PATCH 033/126] Remove dead link in .gitignore Fixes #1972 --- {{cookiecutter.project_slug}}/.gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/.gitignore b/{{cookiecutter.project_slug}}/.gitignore index 1874e9d9..cb8ad835 100644 --- a/{{cookiecutter.project_slug}}/.gitignore +++ b/{{cookiecutter.project_slug}}/.gitignore @@ -325,7 +325,6 @@ tags ### VirtualEnv template # Virtualenv -# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ [Bb]in [Ii]nclude [Ll]ib From 91585a0eb23b8c244e664e6078e2da525e2d14de Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Wed, 20 Mar 2019 12:54:58 +0000 Subject: [PATCH 034/126] Add OS requirements for Ubuntu Bionic 18.04 Fixes #1973 --- .../utility/requirements-bionic.apt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 {{cookiecutter.project_slug}}/utility/requirements-bionic.apt diff --git a/{{cookiecutter.project_slug}}/utility/requirements-bionic.apt b/{{cookiecutter.project_slug}}/utility/requirements-bionic.apt new file mode 100644 index 00000000..1ca82b26 --- /dev/null +++ b/{{cookiecutter.project_slug}}/utility/requirements-bionic.apt @@ -0,0 +1,23 @@ +##basic build dependencies of various Django apps for Ubuntu Bionic 18.04 +#build-essential metapackage install: make, gcc, g++, +build-essential +#required to translate +gettext +python3-dev + +##shared dependencies of: +##Pillow, pylibmc +zlib1g-dev + +##Postgresql and psycopg2 dependencies +libpq-dev + +##Pillow dependencies +libtiff5-dev +libjpeg8-dev +libfreetype6-dev +liblcms2-dev +libwebp-dev + +##django-extensions +libgraphviz-dev From 1ed1e6ac47d9ee9101034a110762e0074060894a Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:00:43 +0000 Subject: [PATCH 035/126] Update sentry-sdk from 0.7.6 to 0.7.7 --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 628a67bd..07e76646 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 Collectfast==0.6.2 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==0.7.6 # https://github.com/getsentry/sentry-python +sentry-sdk==0.7.7 # https://github.com/getsentry/sentry-python {%- endif %} # Django From 4cd30e4657e2dbce3c7d19d02e9db2ae5ed8e6fd Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:00:47 +0000 Subject: [PATCH 036/126] Update django-anymail from 5.0 to 6.0 --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 628a67bd..e4f09c38 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -14,4 +14,4 @@ sentry-sdk==0.7.6 # https://github.com/getsentry/sentry-python # Django # ------------------------------------------------------------------------------ django-storages[boto3]==1.7.1 # https://github.com/jschneier/django-storages -django-anymail[mailgun]==5.0 # https://github.com/anymail/django-anymail +django-anymail[mailgun]==6.0 # https://github.com/anymail/django-anymail From bb26ed565beca0cc9c04199eec6b4e9fa66ee69d Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:00:50 +0000 Subject: [PATCH 037/126] Update python-slugify from 2.0.1 to 3.0.0 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index cbc9485f..fdfec62b 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,5 +1,5 @@ pytz==2018.9 # https://github.com/stub42/pytz -python-slugify==2.0.1 # https://github.com/un33k/python-slugify +python-slugify==3.0.0 # 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' and use_docker == 'n' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin From dd85d6df39cb3167a39a613ec2ceb4c7f9c0722b Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:00:57 +0000 Subject: [PATCH 038/126] Update django-allauth from 0.38.0 to 0.39.1 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index cbc9485f..956587ef 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -22,7 +22,7 @@ flower==0.9.3 # https://github.com/mher/flower 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.38.0 # https://github.com/pennersr/django-allauth +django-allauth==0.39.1 # 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 From f04e96e30f3efb266e03555ce61929e966f4db23 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:01:00 +0000 Subject: [PATCH 039/126] Update djangorestframework from 3.9.1 to 3.9.2 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index cbc9485f..fe5aaf26 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -30,5 +30,5 @@ django-compressor==2.2 # https://github.com/django-compressor/django-compressor django-redis==4.10.0 # https://github.com/niwinz/django-redis # Django REST Framework -djangorestframework==3.9.1 # https://github.com/encode/django-rest-framework +djangorestframework==3.9.2 # https://github.com/encode/django-rest-framework coreapi==2.3.3 # https://github.com/core-api/python-client From 7b83d47e2b44ea60d9e65696889aa470b3522b42 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:01:05 +0000 Subject: [PATCH 040/126] Update werkzeug from 0.14.1 to 0.15.0 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index c9fbb96e..8c7bc694 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -1,6 +1,6 @@ -r ./base.txt -Werkzeug==0.14.1 # https://github.com/pallets/werkzeug +Werkzeug==0.15.0 # https://github.com/pallets/werkzeug ipdb==0.11 # https://github.com/gotcha/ipdb Sphinx==1.8.4 # https://github.com/sphinx-doc/sphinx {%- if cookiecutter.use_docker == 'y' %} From f67a78903ef67148b1b3d7c1d4807f396ab06494 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:01:08 +0000 Subject: [PATCH 041/126] Update ipdb from 0.11 to 0.12 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index c9fbb96e..3e56c1bc 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -1,7 +1,7 @@ -r ./base.txt Werkzeug==0.14.1 # https://github.com/pallets/werkzeug -ipdb==0.11 # https://github.com/gotcha/ipdb +ipdb==0.12 # https://github.com/gotcha/ipdb 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 From b5ab945ca2b6b50fcee8708d9e8b1c4db86e30d7 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:01:14 +0000 Subject: [PATCH 042/126] Update sphinx from 1.8.4 to 1.8.5 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index c9fbb96e..7159a06e 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -2,7 +2,7 @@ Werkzeug==0.14.1 # https://github.com/pallets/werkzeug ipdb==0.11 # https://github.com/gotcha/ipdb -Sphinx==1.8.4 # https://github.com/sphinx-doc/sphinx +Sphinx==1.8.5 # https://github.com/sphinx-doc/sphinx {%- if cookiecutter.use_docker == 'y' %} psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 {%- else %} From a7163b9409543e69026896b70a4d8ff45b9bb716 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:01:18 +0000 Subject: [PATCH 043/126] Update pytest from 4.2.0 to 4.3.1 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index c9fbb96e..0c77b17b 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -12,7 +12,7 @@ psycopg2-binary==2.7.7 # https://github.com/psycopg/psycopg2 # Testing # ------------------------------------------------------------------------------ mypy==0.670 # https://github.com/python/mypy -pytest==4.2.0 # https://github.com/pytest-dev/pytest +pytest==4.3.1 # https://github.com/pytest-dev/pytest pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar # Code quality From 3995e9e807297167bfed646597e4863c991f9317 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:01:21 +0000 Subject: [PATCH 044/126] Update coverage from 4.5.2 to 4.5.3 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index c9fbb96e..6b830959 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -18,7 +18,7 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar # Code quality # ------------------------------------------------------------------------------ flake8==3.7.5 # https://github.com/PyCQA/flake8 -coverage==4.5.2 # https://github.com/nedbat/coveragepy +coverage==4.5.3 # https://github.com/nedbat/coveragepy black==18.9b0 # https://github.com/ambv/black # Django From d92754684f89450a05020fda90bcd2acc4345a15 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:01:24 +0000 Subject: [PATCH 045/126] Update black from 18.9b0 to 19.3b0 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index c9fbb96e..f8e3e96c 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -19,7 +19,7 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar # ------------------------------------------------------------------------------ flake8==3.7.5 # https://github.com/PyCQA/flake8 coverage==4.5.2 # https://github.com/nedbat/coveragepy -black==18.9b0 # https://github.com/ambv/black +black==19.3b0 # https://github.com/ambv/black # Django # ------------------------------------------------------------------------------ From a8c52e2d455a82d43dda8021ca4691776b27f3d0 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:01:28 +0000 Subject: [PATCH 046/126] Update django-extensions from 2.1.5 to 2.1.6 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index c9fbb96e..18ef4aac 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -26,6 +26,6 @@ black==18.9b0 # https://github.com/ambv/black factory-boy==2.11.1 # https://github.com/FactoryBoy/factory_boy 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-extensions==2.1.6 # https://github.com/django-extensions/django-extensions django-coverage-plugin==1.6.0 # https://github.com/nedbat/django_coverage_plugin pytest-django==3.4.7 # https://github.com/pytest-dev/pytest-django From 65d315ed292224039e4fc2f76c8b7bb1954992fc Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 21 Mar 2019 16:01:31 +0000 Subject: [PATCH 047/126] Update pytest-django from 3.4.7 to 3.4.8 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index c9fbb96e..70ebedfc 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -28,4 +28,4 @@ factory-boy==2.11.1 # https://github.com/FactoryBoy/factory_boy 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.7 # https://github.com/pytest-dev/pytest-django +pytest-django==3.4.8 # https://github.com/pytest-dev/pytest-django From 7f3aa6cebb9f2efb188e2b01acd90b184e2e72b3 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Fri, 22 Mar 2019 11:00:31 +0000 Subject: [PATCH 048/126] Update werkzeug from 0.15.0 to 0.15.1 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 2fa606c1..df1ef007 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -1,6 +1,6 @@ -r ./base.txt -Werkzeug==0.15.0 # https://github.com/pallets/werkzeug +Werkzeug==0.15.1 # https://github.com/pallets/werkzeug ipdb==0.12 # https://github.com/gotcha/ipdb Sphinx==1.8.5 # https://github.com/sphinx-doc/sphinx {%- if cookiecutter.use_docker == 'y' %} From 85aea55fc64d117a31ffe50e481a1e2de17e3385 Mon Sep 17 00:00:00 2001 From: Hana Quadara Date: Sat, 23 Mar 2019 00:01:23 -0400 Subject: [PATCH 049/126] add plugins to req file; remove pylint-common --- docs/linters.rst | 2 +- requirements.txt | 2 ++ {{cookiecutter.project_slug}}/.pylintrc | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/linters.rst b/docs/linters.rst index e59ff0df..2d623218 100644 --- a/docs/linters.rst +++ b/docs/linters.rst @@ -25,7 +25,7 @@ This is included in flake8's checks, but you can also run it separately to see a The config for pylint is located in .pylintrc. It specifies: -* Use the pylint_common and pylint_django plugins. If using Celery, also use pylint_celery. +* Use the pylint_django plugin. If using Celery, also use pylint_celery. * Set max line length to 120 chars * Disable linting messages for missing docstring and invalid name * max-parents=13 diff --git a/requirements.txt b/requirements.txt index 647bccae..ce2cd07e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,8 @@ binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ flake8==3.7.6 +pylint-django==0.9.4 +pylint-celery==0.3 # Testing # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/.pylintrc b/{{cookiecutter.project_slug}}/.pylintrc index 1a199286..a0955f07 100644 --- a/{{cookiecutter.project_slug}}/.pylintrc +++ b/{{cookiecutter.project_slug}}/.pylintrc @@ -1,5 +1,5 @@ [MASTER] -load-plugins=pylint_common, pylint_django{% if cookiecutter.use_celery == "y" %}, pylint_celery {% endif %} +load-plugins=pylint_django{% if cookiecutter.use_celery == "y" %}, pylint_celery {% endif %} [FORMAT] max-line-length=120 From 015319ca3f63fd4720dda4737ac5c56764ea75ef Mon Sep 17 00:00:00 2001 From: Hana Quadara Date: Sat, 23 Mar 2019 00:26:13 -0400 Subject: [PATCH 050/126] add username to contributors --- CONTRIBUTORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index b7607562..24d8fda6 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -106,6 +106,7 @@ Listed in alphabetical order. Garry Cairns `@garry-cairns`_ Garry Polley `@garrypolley`_ Hamish Durkin `@durkode`_ + Hana Quadara `@hanaquadara`_ Harry Percival `@hjwp`_ Hendrik Schneider `@hendrikschneider`_ Henrique G. G. Pereira `@ikkebr`_ From b91c70d75578e56c2ca74400684c5b5523cd0cd4 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 25 Mar 2019 12:10:55 +0000 Subject: [PATCH 051/126] Add a node image to run Gulp when selecting it with Docker (#1687) ## Description Following up on @webyneter attempt in #1205, which is now getting outdated, I've tried to make Gulp task runner work with Docker. There is no documentation yet, but this seems to work locally with the custom bootstrap compilation... - [x] Add a node image for local developement - [x] Proxy the django image rather than localhost in Browser sync, pass header to keep hostname - [x] Don't call the runserver command from Gulp, let docker-compose handle - [x] Update package.json & gulpfile.js templates to reduce the number of unwanted empty lines - [x] Use [multi-stage build](https://docs.docker.com/develop/develop-images/multistage-build/) in production to make sure the static assets are produced - [x] Update documentation - [x] Verify that the previous issue with static assets missing from production isn't there ## Rationale Currently, the static build isn't working nicely with Docker, extra manual setup is required. Fixes #1762 --- docs/deployment-with-docker.rst | 5 +++-- hooks/post_gen_project.py | 21 ++++++------------- .../compose/local/node/Dockerfile | 9 ++++++++ .../compose/production/django/Dockerfile | 21 +++++++++++++++++-- {{cookiecutter.project_slug}}/gulpfile.js | 20 +++++++++++++++++- {{cookiecutter.project_slug}}/local.yml | 20 ++++++++++++++++++ {{cookiecutter.project_slug}}/package.json | 5 +++-- .../templates/base.html | 8 +++---- 8 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 {{cookiecutter.project_slug}}/compose/local/node/Dockerfile diff --git a/docs/deployment-with-docker.rst b/docs/deployment-with-docker.rst index 904947e3..4ab2312e 100644 --- a/docs/deployment-with-docker.rst +++ b/docs/deployment-with-docker.rst @@ -7,8 +7,8 @@ Deployment with Docker Prerequisites ------------- -* Docker 1.10+. -* Docker Compose 1.6+ +* Docker 17.05+. +* Docker Compose 1.17+ Understanding the Docker Compose Setup @@ -144,3 +144,4 @@ Move it to ``/etc/supervisor/conf.d/{{cookiecutter.project_slug}}.conf`` and run For status check, run:: supervisorctl status + diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index a9c1c941..ab05b375 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -267,6 +267,10 @@ def remove_celery_compose_dirs(): shutil.rmtree(os.path.join("compose", "production", "django", "celery")) +def remove_node_dockerfile(): + shutil.rmtree(os.path.join("compose", "local", "node")) + + def main(): debug = "{{ cookiecutter.debug }}".lower() == "y" @@ -313,21 +317,8 @@ def main(): if "{{ cookiecutter.js_task_runner}}".lower() == "none": remove_gulp_files() remove_packagejson_file() - if ( - "{{ cookiecutter.js_task_runner }}".lower() != "none" - and "{{ cookiecutter.use_docker }}".lower() == "y" - ): - print( - WARNING - + "Docker and {} JS task runner ".format( - "{{ cookiecutter.js_task_runner }}".lower().capitalize() - ) - + "working together not supported yet. " - "You can continue using the generated project like you " - "normally would, however you would need to add a JS " - "task runner service to your Docker Compose configuration " - "manually." + TERMINATOR - ) + if "{{ cookiecutter.use_docker }}".lower() == "y": + remove_node_dockerfile() if "{{ cookiecutter.use_celery }}".lower() == "n": remove_celery_app() diff --git a/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile new file mode 100644 index 00000000..f9976e20 --- /dev/null +++ b/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile @@ -0,0 +1,9 @@ +FROM node:10-stretch-slim + +WORKDIR /app + +COPY ./package.json /app + +RUN npm install && npm cache clean --force + +ENV PATH ./node_modules/.bin/:$PATH diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile index 68d72327..80b5bc2c 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile @@ -1,3 +1,14 @@ +{% if cookiecutter.js_task_runner == 'Gulp' -%} +FROM node:10-stretch-slim as client-builder + +WORKDIR /app +COPY ./package.json /app +RUN npm install && npm cache clean --force +COPY . /app +RUN npm run build + +# Python build stage +{%- endif %} FROM python:3.6-alpine ENV PYTHONUNBUFFERED 1 @@ -28,7 +39,8 @@ COPY ./compose/production/django/start /start RUN sed -i 's/\r//' /start RUN chmod +x /start RUN chown django /start -{% if cookiecutter.use_celery == "y" %} + +{%- if cookiecutter.use_celery == "y" %} COPY ./compose/production/django/celery/worker/start /start-celeryworker RUN sed -i 's/\r//' /start-celeryworker RUN chmod +x /start-celeryworker @@ -42,8 +54,13 @@ RUN chown django /start-celerybeat COPY ./compose/production/django/celery/flower/start /start-flower RUN sed -i 's/\r//' /start-flower RUN chmod +x /start-flower -{% endif %} +{%- endif %} + +{%- if cookiecutter.js_task_runner == 'Gulp' %} +COPY --from=client-builder /app /app +{% else %} COPY . /app +{%- endif %} RUN chown -R django /app diff --git a/{{cookiecutter.project_slug}}/gulpfile.js b/{{cookiecutter.project_slug}}/gulpfile.js index d92678ed..3c28a735 100644 --- a/{{cookiecutter.project_slug}}/gulpfile.js +++ b/{{cookiecutter.project_slug}}/gulpfile.js @@ -127,7 +127,23 @@ function initBrowserSync() { `${paths.js}/*.js`, `${paths.templates}/*.html` ], { - proxy: "localhost:8000" + // https://www.browsersync.io/docs/options/#option-proxy + {%- if cookiecutter.use_docker == 'n' %} + proxy: 'localhost:8000' + {% else %} + proxy: { + target: 'django:8000', + proxyReq: [ + function(proxyReq, req) { + // Assign proxy "host" header same as current request at Browsersync server + proxyReq.setHeader('Host', req.headers.host) + } + ] + }, + // https://www.browsersync.io/docs/options/#option-open + // Disable as it doesn't work from inside a container + open: false + {%- endif %} } ) } @@ -149,7 +165,9 @@ const generateAssets = parallel( // Set up dev environment const dev = parallel( + {%- if cookiecutter.use_docker == 'n' %} runServer, + {%- endif %} initBrowserSync, watchPaths ) diff --git a/{{cookiecutter.project_slug}}/local.yml b/{{cookiecutter.project_slug}}/local.yml index 36638932..c6dd654e 100644 --- a/{{cookiecutter.project_slug}}/local.yml +++ b/{{cookiecutter.project_slug}}/local.yml @@ -79,3 +79,23 @@ services: command: /start-flower {%- endif %} + {%- if cookiecutter.js_task_runner == 'Gulp' %} + + node: + build: + context: . + dockerfile: ./compose/local/node/Dockerfile + image: {{ cookiecutter.project_slug }}_local_node + depends_on: + - django + volumes: + - .:/app + # http://jdlm.info/articles/2016/03/06/lessons-building-node-app-docker.html + - /app/node_modules + command: npm run dev + ports: + - "3000:3000" + # Expose browsersync UI: https://www.browsersync.io/docs/options/#option-ui + - "3001:3001" + + {%- endif %} diff --git a/{{cookiecutter.project_slug}}/package.json b/{{cookiecutter.project_slug}}/package.json index a15df941..6edf2e11 100644 --- a/{{cookiecutter.project_slug}}/package.json +++ b/{{cookiecutter.project_slug}}/package.json @@ -5,7 +5,7 @@ "devDependencies": { {% if cookiecutter.js_task_runner == 'Gulp' -%} {% if cookiecutter.custom_bootstrap_compilation == 'y' -%} - "bootstrap": "4.1.1", + "bootstrap": "4.3.1", "gulp-concat": "^2.6.1", "jquery": "3.3.1", "popper.js": "1.14.3", @@ -31,7 +31,8 @@ ], "scripts": { {% if cookiecutter.js_task_runner == 'Gulp' -%} - "dev": "gulp" + "dev": "gulp", + "build": "gulp generate-assets" {%- endif %} } } diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html index 4470e955..9caab43a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html @@ -17,8 +17,8 @@ {% block css %} {% endraw %}{% if cookiecutter.custom_bootstrap_compilation == "n" %}{% raw %} - - + + {% endraw %}{% endif %}{% raw %} @@ -102,10 +102,10 @@ {% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %} {% endraw %}{% else %}{% raw %} - + - + {% endraw %}{% endif %}{% raw %} From ec79f1f6763e097df152649353bea5f08ffa2023 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 25 Mar 2019 19:04:47 +0000 Subject: [PATCH 052/126] Rename test phases in Travis build matrix --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 65b2a28d..a74090b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,9 @@ before_install: matrix: include: - - name: Test + - name: Tox Test script: tox -e py36 - - name: Black + - name: Black template script: tox -e black - name: Basic Docker script: sh tests/test_docker.sh From b261ce27c4351996d5186f37a56c3b72e6330e0c Mon Sep 17 00:00:00 2001 From: hanasuhail Date: Mon, 25 Mar 2019 15:52:49 -0400 Subject: [PATCH 053/126] update restructured text link; add condition for celery linter --- CONTRIBUTORS.rst | 1 + requirements.txt | 2 -- {{cookiecutter.project_slug}}/requirements/local.txt | 4 ++++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 24d8fda6..154fa1ac 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -312,6 +312,7 @@ Listed in alphabetical order. .. _@saschalalala: https://github.com/saschalalala .. _@mrcoles: https://github.com/mrcoles .. _@ericgroom: https://github.com/ericgroom +.. _@hanaquadara: https://github.com/hanaquadara Special Thanks ~~~~~~~~~~~~~~ diff --git a/requirements.txt b/requirements.txt index ce2cd07e..647bccae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,8 +5,6 @@ binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ flake8==3.7.6 -pylint-django==0.9.4 -pylint-celery==0.3 # Testing # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index df1ef007..d3ad17fd 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -20,6 +20,10 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar flake8==3.7.5 # https://github.com/PyCQA/flake8 coverage==4.5.3 # https://github.com/nedbat/coveragepy black==19.3b0 # https://github.com/ambv/black +pylint-django==0.9.4 +{%- if cookiecutter.use_celery == 'y' %} +pylint-celery==0.3 +{%- endif %} # Django # ------------------------------------------------------------------------------ From 5db400fbcf6263cbefb18a0d28ae7c448e785c14 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Tue, 26 Mar 2019 11:00:32 +0000 Subject: [PATCH 054/126] Update sentry-sdk from 0.7.7 to 0.7.8 --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 1d842de4..17b9d00c 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 Collectfast==0.6.2 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==0.7.7 # https://github.com/getsentry/sentry-python +sentry-sdk==0.7.8 # https://github.com/getsentry/sentry-python {%- endif %} # Django From 99d7e1d5efd9328c5ce4aa94510efcf1070885a2 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Tue, 26 Mar 2019 11:00:35 +0000 Subject: [PATCH 055/126] Update python-slugify from 3.0.0 to 3.0.1 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index e26f6536..e0a76232 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,5 +1,5 @@ pytz==2018.9 # https://github.com/stub42/pytz -python-slugify==3.0.0 # https://github.com/un33k/python-slugify +python-slugify==3.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' and use_docker == 'n' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin From c2f8569eb375d6e4d5ef80c32c339a8529478678 Mon Sep 17 00:00:00 2001 From: hanasuhail Date: Tue, 26 Mar 2019 17:16:40 -0400 Subject: [PATCH 056/126] add sources --- {{cookiecutter.project_slug}}/requirements/local.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index d3ad17fd..066f01ad 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -20,9 +20,9 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar flake8==3.7.5 # https://github.com/PyCQA/flake8 coverage==4.5.3 # https://github.com/nedbat/coveragepy black==19.3b0 # https://github.com/ambv/black -pylint-django==0.9.4 +pylint-django==0.9.4 # https://github.com/PyCQA/pylint-django {%- if cookiecutter.use_celery == 'y' %} -pylint-celery==0.3 +pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery {%- endif %} # Django From 9e93adaf98a1da5b4befe113f22a2ae646094d36 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 26 Mar 2019 21:20:56 +0000 Subject: [PATCH 057/126] Add documentation to include optional integrations fixes #449 --- docs/deployment-on-heroku.rst | 65 +++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/docs/deployment-on-heroku.rst b/docs/deployment-on-heroku.rst index 09953cf8..6f3076bc 100644 --- a/docs/deployment-on-heroku.rst +++ b/docs/deployment-on-heroku.rst @@ -17,11 +17,8 @@ Run these commands to deploy the project to Heroku: heroku addons:create heroku-redis:hobby-dev - # If using mailgun: heroku addons:create mailgun:starter - heroku addons:create sentry:f1 - heroku config:set PYTHONHASHSEED=random heroku config:set WEB_CONCURRENCY=4 @@ -52,3 +49,65 @@ Run these commands to deploy the project to Heroku: heroku run python manage.py check --deploy heroku open + + +Optional actions +---------------- + +Celery +++++++ + +Celery requires a few extra environment variables to be ready operational. Also, the worker is created, +it's in the ``Procfile``, but is turned off by default: + +.. code-block:: bash + + # Set the broker URL to Redis + heroku config:set CELERY_BROKER_URL=`heroku config:get REDIS_URL` + # Scale dyno to 1 instance + heroku ps:scale worker=1 + +Sentry +++++++ + +If you're opted for Sentry error tracking, you can either install it through the `Sentry add-on`_: + +.. code-block:: bash + + heroku addons:create sentry:f1 + + +Or add the DSN for your account, if you already have one: + +.. code-block:: bash + + heroku config:set SENTRY_DSN=https://xxxx@sentry.io/12345 + +.. _Sentry add-on: https://elements.heroku.com/addons/sentry + + +Gulp & Bootstrap compilation +++++++++++++++++++++++++++++ + +If you've opted for a custom bootstrap build, you'll most likely need to setup +your app to use `multiple buildpacks`_: one for Python & one for Node.js: + +.. code-block:: bash + + heroku buildpacks:add --index 1 heroku/nodejs + +At time of writing, this should do the trick: during deployment, +the Heroku should run ``npm install`` and then ``npm build``, +which runs Gulp in cookiecutter-django. + +If things don't work, please refer to the Heroku docs. + +.. _multiple buildpacks: https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app + +About Heroku & Docker +--------------------- + +Although Heroku has some sort of `Docker support`_, it's not supported by cookiecutter-django. +We invite you to follow Heroku documentation about it. + +.. _Docker support:: https://devcenter.heroku.com/articles/build-docker-images-heroku-yml From eb3325f767264190fbc1305547d7d3bfd8bedb06 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 26 Mar 2019 21:36:38 +0000 Subject: [PATCH 058/126] Add documentation about Mailgun setup fixes #1705 --- docs/deployment-on-heroku.rst | 5 +++++ docs/deployment-with-docker.rst | 5 +++++ docs/mailgun.rst | 13 +++++++++++++ docs/troubleshooting.rst | 2 ++ 4 files changed, 25 insertions(+) create mode 100644 docs/mailgun.rst diff --git a/docs/deployment-on-heroku.rst b/docs/deployment-on-heroku.rst index 6f3076bc..8cc3a6b5 100644 --- a/docs/deployment-on-heroku.rst +++ b/docs/deployment-on-heroku.rst @@ -51,6 +51,11 @@ Run these commands to deploy the project to Heroku: heroku open +.. warning:: + + .. include:: mailgun.rst + + Optional actions ---------------- diff --git a/docs/deployment-with-docker.rst b/docs/deployment-with-docker.rst index 4ab2312e..aad54932 100644 --- a/docs/deployment-with-docker.rst +++ b/docs/deployment-with-docker.rst @@ -43,6 +43,11 @@ You will probably also need to setup the Mail backend, for example by adding a ` .. _Mailgun: https://mailgun.com +.. warning:: + + .. include:: mailgun.rst + + Optional: Use AWS IAM Role for EC2 instance ------------------------------------------- diff --git a/docs/mailgun.rst b/docs/mailgun.rst new file mode 100644 index 00000000..1f34e3c8 --- /dev/null +++ b/docs/mailgun.rst @@ -0,0 +1,13 @@ +If your email server used to send email isn't configured properly (Mailgun by default), +attempting to send an email will cause an Internal Server Error. + +By default, django-allauth is setup to `have emails verifications mandatory`_, +which means it'll send a verification email when an unverified user tries to +log-in or when someone tries to sign-up. + +This may happen just after you've setup your Mailgun account, which is running in a +sandbox subdomain by default. Either add your email to the list of authorized recipients +or verify your domain. + + +.. _have emails verifications mandatory: https://django-allauth.readthedocs.io/en/latest/configuration.html?highlight=ACCOUNT_EMAIL_VERIFICATION diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index d0c0ba43..68db2fb0 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -11,5 +11,7 @@ This page contains some advice about errors and problems commonly encountered du #. 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`_) +#. .. include:: mailgun.rst + .. _#528: https://github.com/pydanny/cookiecutter-django/issues/528#issuecomment-212650373 .. _#1725: https://github.com/pydanny/cookiecutter-django/issues/1725#issuecomment-407493176 From 28c60116a6a9e8eaa1131da7223e67872787b370 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Wed, 27 Mar 2019 11:00:31 +0000 Subject: [PATCH 059/126] Update pylint-django from 0.9.4 to 2.0.6 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 066f01ad..0c6886f7 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -20,7 +20,7 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar flake8==3.7.5 # https://github.com/PyCQA/flake8 coverage==4.5.3 # https://github.com/nedbat/coveragepy black==19.3b0 # https://github.com/ambv/black -pylint-django==0.9.4 # https://github.com/PyCQA/pylint-django +pylint-django==2.0.6 # https://github.com/PyCQA/pylint-django {%- if cookiecutter.use_celery == 'y' %} pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery {%- endif %} From 7e60f1259a3d25b25d6dd4eec19bc2a88335fc44 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 27 Mar 2019 14:15:44 -0700 Subject: [PATCH 060/126] Update tox from 3.6.1 to 3.8.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 647bccae..01e826cd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ -tox==3.6.1 +tox==3.8.0 pytest==4.3.1 pytest-cookies==0.3.0 pyyaml==5.1 From becd2dce1329670f5286ac6435e5ef9b7d8ae8aa Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Wed, 27 Mar 2019 21:27:52 +0000 Subject: [PATCH 061/126] Reword & clarify Python 2 warning in pre gen hook Fixes #1942 --- hooks/pre_gen_project.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index a6b83455..e7bc1e39 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -30,9 +30,8 @@ if "{{ cookiecutter.use_docker }}".lower() == "n": python_major_version = sys.version_info[0] if python_major_version == 2: print( - WARNING + "Cookiecutter Django does not support Python 2. " - "Stability is guaranteed with Python 3.6+ only, " - "are you sure you want to proceed (y/n)? " + TERMINATOR + WARNING + "You're running cookiecutter under Python 2, but the generated " + "project requires Python 3.6+. Do you want to proceed (y/n)? " + TERMINATOR ) yes_options, no_options = frozenset(["y"]), frozenset(["n"]) while True: From c33417aa427f4923ce584d6274042d619fe8a4c4 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Thu, 28 Mar 2019 18:52:24 -0700 Subject: [PATCH 062/126] Update tox from 3.8.0 to 3.8.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 01e826cd..d0c1602d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ -tox==3.8.0 +tox==3.8.1 pytest==4.3.1 pytest-cookies==0.3.0 pyyaml==5.1 From 3b6f73afb252ca0e283696006faf06c0dac021ff Mon Sep 17 00:00:00 2001 From: browniebroke Date: Fri, 29 Mar 2019 11:00:31 +0000 Subject: [PATCH 063/126] Update sphinx from 1.8.5 to 2.0.0 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 0c6886f7..baac837c 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -2,7 +2,7 @@ Werkzeug==0.15.1 # https://github.com/pallets/werkzeug ipdb==0.12 # https://github.com/gotcha/ipdb -Sphinx==1.8.5 # https://github.com/sphinx-doc/sphinx +Sphinx==2.0.0 # https://github.com/sphinx-doc/sphinx {%- if cookiecutter.use_docker == 'y' %} psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 {%- else %} From da51b7a364e2ff8b509208e2e62e025ced443a5e Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Fri, 29 Mar 2019 09:58:15 -0700 Subject: [PATCH 064/126] Update tox from 3.8.1 to 3.8.3 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d0c1602d..f5435958 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ -tox==3.8.1 +tox==3.8.3 pytest==4.3.1 pytest-cookies==0.3.0 pyyaml==5.1 From 1bc185d2f7289b481a56165a11bbe39c32d2f983 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Sun, 31 Mar 2019 12:00:28 +0100 Subject: [PATCH 065/126] Update sentry-sdk from 0.7.8 to 0.7.9 --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 17b9d00c..035cefd7 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 Collectfast==0.6.2 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==0.7.8 # https://github.com/getsentry/sentry-python +sentry-sdk==0.7.9 # https://github.com/getsentry/sentry-python {%- endif %} # Django From 4e70a4b55a2d5efafdb9761719bafb1b6ece3154 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 1 Apr 2019 08:47:46 +0100 Subject: [PATCH 066/126] Test all possible template combinations (#1993) ## Description Fixes #591. ## Rationale We are currently not testing many combinations, we run Flake8 on the generated project with default options, but that rarely catch any issues. ## Use case(s) / visualization(s) Catch problems with invalid combinations, for instance, it fails due to Whitenoise breaking flake8 with `django-compressor` because `STATIC_URL` was undefined here: https://github.com/pydanny/cookiecutter-django/blob/b91c70d75578e56c2ca74400684c5b5523cd0cd4/%7B%7Bcookiecutter.project_slug%7D%7D/config/settings/production.py#L185 --- requirements.txt | 2 + tests/test_cookiecutter_generation.py | 76 +++++++++++++------ .../config/settings/base.py | 4 +- .../config/settings/production.py | 2 +- .../requirements/base.txt | 2 +- 5 files changed, 57 insertions(+), 29 deletions(-) diff --git a/requirements.txt b/requirements.txt index f5435958..a44e1fe4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,11 +4,13 @@ binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ +black==19.3b0 flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ tox==3.8.3 pytest==4.3.1 +pytest_cases==1.5.1 pytest-cookies==0.3.0 pyyaml==5.1 diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index 3010d364..36395627 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -1,14 +1,17 @@ import os import re -import sh -import yaml import pytest +from pytest_cases import pytest_fixture_plus +import sh +import yaml from binaryornot.check import is_binary PATTERN = "{{(\s?cookiecutter)[.](.*?)}}" RE_OBJ = re.compile(PATTERN) +YN_CHOICES = ["y", "n"] + @pytest.fixture def context(): @@ -24,6 +27,35 @@ def context(): } +@pytest_fixture_plus +@pytest.mark.parametrize("windows", YN_CHOICES, ids=lambda yn: f"win:{yn}") +@pytest.mark.parametrize("use_docker", YN_CHOICES, ids=lambda yn: f"docker:{yn}") +@pytest.mark.parametrize("use_celery", YN_CHOICES, ids=lambda yn: f"celery:{yn}") +@pytest.mark.parametrize("use_mailhog", YN_CHOICES, ids=lambda yn: f"mailhog:{yn}") +@pytest.mark.parametrize("use_sentry", YN_CHOICES, ids=lambda yn: f"sentry:{yn}") +@pytest.mark.parametrize("use_compressor", YN_CHOICES, ids=lambda yn: f"cmpr:{yn}") +@pytest.mark.parametrize("use_whitenoise", YN_CHOICES, ids=lambda yn: f"wnoise:{yn}") +def context_combination( + windows, + use_docker, + use_celery, + use_mailhog, + use_sentry, + use_compressor, + use_whitenoise, +): + """Fixture that parametrize the function where it's used.""" + return { + "windows": windows, + "use_docker": use_docker, + "use_compressor": use_compressor, + "use_celery": use_celery, + "use_mailhog": use_mailhog, + "use_sentry": use_sentry, + "use_whitenoise": use_whitenoise, + } + + def build_files_list(root_dir): """Build a list containing absolute paths to the generated files.""" return [ @@ -48,8 +80,13 @@ def check_paths(paths): assert match is None, msg.format(path) -def test_default_configuration(cookies, context): - result = cookies.bake(extra_context=context) +def test_project_generation(cookies, context, context_combination): + """ + Test that project is generated and fully rendered. + + This is parametrized for each combination from ``context_combination`` fixture + """ + result = cookies.bake(extra_context={**context, **context_combination}) assert result.exit_code == 0 assert result.exception is None assert result.project.basename == context["project_slug"] @@ -60,33 +97,24 @@ def test_default_configuration(cookies, context): check_paths(paths) -@pytest.fixture(params=["use_mailhog", "use_celery", "windows"]) -def feature_context(request, context): - context.update({request.param: "y"}) - return context +def test_linting_passes(cookies, context_combination): + """ + Generated project should pass flake8 & black. - -def test_enabled_features(cookies, feature_context): - result = cookies.bake(extra_context=feature_context) - assert result.exit_code == 0 - assert result.exception is None - assert result.project.basename == feature_context["project_slug"] - assert result.project.isdir() - - paths = build_files_list(str(result.project)) - assert paths - check_paths(paths) - - -def test_flake8_compliance(cookies): - """generated project should pass flake8""" - result = cookies.bake() + This is parametrized for each combination from ``context_combination`` fixture + """ + result = cookies.bake(extra_context=context_combination) try: sh.flake8(str(result.project)) except sh.ErrorReturnCode as e: pytest.fail(e) + try: + sh.black("--check", "--diff", "--exclude", "migrations", f"{result.project}/") + except sh.ErrorReturnCode as e: + pytest.fail(e) + def test_travis_invokes_pytest(cookies, context): context.update({"use_travisci": "y"}) diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py index 848af8e8..f8d22377 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -43,9 +43,7 @@ USE_TZ = True DATABASES = {"default": env.db("DATABASE_URL")} {%- else %} DATABASES = { - "default": env.db( - "DATABASE_URL", default="postgres://{% if cookiecutter.windows == 'y' %}localhost{% endif %}/{{cookiecutter.project_slug}}" - ), + "default": env.db("DATABASE_URL", default="postgres://{% if cookiecutter.windows == 'y' %}localhost{% endif %}/{{cookiecutter.project_slug}}") } {%- endif %} DATABASES["default"]["ATOMIC_REQUESTS"] = True diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 546f2364..3db964b6 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -182,7 +182,7 @@ COMPRESS_ENABLED = env.bool("COMPRESS_ENABLED", default=True) # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE COMPRESS_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL -COMPRESS_URL = STATIC_URL +COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' %} # noqa F405{% endif %} {% endif %} {%- if cookiecutter.use_whitenoise == 'n' -%} # Collectfast diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index e0a76232..a1fa9b06 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -2,7 +2,7 @@ pytz==2018.9 # https://github.com/stub42/pytz python-slugify==3.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' and use_docker == 'n' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin +rcssmin==1.0.6{% if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin {%- endif %} argon2-cffi==19.1.0 # https://github.com/hynek/argon2_cffi {%- if cookiecutter.use_whitenoise == 'y' %} From e55d76529be5133b8bdd10275c615a2f0de93dd7 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Mon, 1 Apr 2019 00:47:56 -0700 Subject: [PATCH 067/126] Update pytest from 4.3.1 to 4.4.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a44e1fe4..85c7fd03 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ tox==3.8.3 -pytest==4.3.1 +pytest==4.4.0 pytest_cases==1.5.1 pytest-cookies==0.3.0 pyyaml==5.1 From 22801fe30e579f3749aa546652a2207cbbc8693b Mon Sep 17 00:00:00 2001 From: browniebroke Date: Mon, 1 Apr 2019 12:00:32 +0100 Subject: [PATCH 068/126] Update python-slugify from 3.0.1 to 3.0.2 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index a1fa9b06..f09448cc 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,5 +1,5 @@ pytz==2018.9 # https://github.com/stub42/pytz -python-slugify==3.0.1 # https://github.com/un33k/python-slugify +python-slugify==3.0.2 # 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' and cookiecutter.use_docker == 'n' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin From e10aafe802aa40067c199a924903adab05c62b79 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Mon, 1 Apr 2019 12:00:35 +0100 Subject: [PATCH 069/126] Update celery from 4.2.1 to 4.3.0 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index a1fa9b06..cb422dd9 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -10,7 +10,7 @@ whitenoise==4.1.2 # https://github.com/evansd/whitenoise {%- endif %} redis==3.2.1 # https://github.com/antirez/redis {%- if cookiecutter.use_celery == "y" %} -celery==4.2.1 # pyup: < 5.0 # https://github.com/celery/celery +celery==4.3.0 # pyup: < 5.0 # https://github.com/celery/celery kombu==4.4.0 # https://github.com/celery/kombu {%- if cookiecutter.use_docker == 'y' %} flower==0.9.3 # https://github.com/mher/flower From faf0e0bc7ef833cb4e3cc99f3c193a82ec4851fe Mon Sep 17 00:00:00 2001 From: browniebroke Date: Mon, 1 Apr 2019 12:00:43 +0100 Subject: [PATCH 070/126] Update pytest from 4.3.1 to 4.4.0 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index baac837c..028886b0 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -12,7 +12,7 @@ psycopg2-binary==2.7.7 # https://github.com/psycopg/psycopg2 # Testing # ------------------------------------------------------------------------------ mypy==0.670 # https://github.com/python/mypy -pytest==4.3.1 # https://github.com/pytest-dev/pytest +pytest==4.4.0 # https://github.com/pytest-dev/pytest pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar # Code quality From b3680c8d723c704c05d5c58f49f954f214a9d78c Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Mon, 1 Apr 2019 12:59:05 +0100 Subject: [PATCH 071/126] Remove Kombu from direct dependencies --- {{cookiecutter.project_slug}}/requirements/base.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index cb422dd9..10f69c57 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -11,7 +11,6 @@ whitenoise==4.1.2 # https://github.com/evansd/whitenoise redis==3.2.1 # https://github.com/antirez/redis {%- if cookiecutter.use_celery == "y" %} celery==4.3.0 # pyup: < 5.0 # https://github.com/celery/celery -kombu==4.4.0 # https://github.com/celery/kombu {%- if cookiecutter.use_docker == 'y' %} flower==0.9.3 # https://github.com/mher/flower {%- endif %} From 96934ab3e4c31e48c810aea70b28c93c84abc9af Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Mon, 1 Apr 2019 20:07:42 -0700 Subject: [PATCH 072/126] Update tox from 3.8.3 to 3.8.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 85c7fd03..aebe0e54 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ -tox==3.8.3 +tox==3.8.4 pytest==4.4.0 pytest_cases==1.5.1 pytest-cookies==0.3.0 From 6d48275e5fd66c412f097f05e7125b5e76b46052 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 2 Apr 2019 10:33:38 +0100 Subject: [PATCH 073/126] Fix Heroku docs --- docs/deployment-on-heroku.rst | 5 ++++- tests/test_docker.sh | 16 ++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/docs/deployment-on-heroku.rst b/docs/deployment-on-heroku.rst index 8cc3a6b5..4a16123a 100644 --- a/docs/deployment-on-heroku.rst +++ b/docs/deployment-on-heroku.rst @@ -3,6 +3,9 @@ Deployment on Heroku .. index:: Heroku +Commands to run +--------------- + Run these commands to deploy the project to Heroku: .. code-block:: bash @@ -115,4 +118,4 @@ About Heroku & Docker Although Heroku has some sort of `Docker support`_, it's not supported by cookiecutter-django. We invite you to follow Heroku documentation about it. -.. _Docker support:: https://devcenter.heroku.com/articles/build-docker-images-heroku-yml +.. _Docker support: https://devcenter.heroku.com/articles/build-docker-images-heroku-yml diff --git a/tests/test_docker.sh b/tests/test_docker.sh index 55771c14..018ad85f 100755 --- a/tests/test_docker.sh +++ b/tests/test_docker.sh @@ -16,17 +16,9 @@ cd .cache/docker cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y $@ cd my_awesome_project -# run the project's type checks -docker-compose -f local.yml run django mypy my_awesome_project +# run migrations +docker-compose -f local.yml run django python manage.py migrate -# Run black with --check option -docker-compose -f local.yml run django black --check --diff --exclude 'migrations' ./ +# view backups +docker-compose -f local.yml exec postgres backups -# run the project's tests -docker-compose -f local.yml run django pytest - -# return non-zero status code if there are migrations that have not been created -docker-compose -f local.yml run django python manage.py makemigrations --dry-run --check || { echo "ERROR: there were changes in the models, but migration listed above have not been created and are not saved in version control"; exit 1; } - -# Test support for translations -docker-compose -f local.yml run django python manage.py makemessages From edf2eba6af19af60befb9741d5c0223eb74834ef Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 2 Apr 2019 10:36:42 +0100 Subject: [PATCH 074/126] Remove outdated warning in Local docker docs --- docs/developing-locally-docker.rst | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/docs/developing-locally-docker.rst b/docs/developing-locally-docker.rst index 10815419..da4e67aa 100644 --- a/docs/developing-locally-docker.rst +++ b/docs/developing-locally-docker.rst @@ -17,17 +17,6 @@ Prerequisites .. _`installation guide`: https://docs.docker.com/compose/install/ -Attention, Windows Users ------------------------- - -Currently PostgreSQL (``psycopg2`` python package) is not installed inside Docker containers for Windows users, while it is required by the generated Django project. To fix this, add ``psycopg2`` to the list of requirements inside ``requirements/base.txt``:: - - # Python-PostgreSQL Database Adapter - psycopg2==2.6.2 - -Doing this will prevent the project from being installed in an Windows-only environment (thus without usage of Docker). If you want to use this project without Docker, make sure to remove ``psycopg2`` from the requirements again. - - Build the Stack --------------- From fbce0c8ba14baa77a5d080f816a0902069b5f491 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Tue, 2 Apr 2019 12:00:29 +0100 Subject: [PATCH 075/126] Update pillow from 5.4.1 to 6.0.0 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index e9cade35..9d4aec7d 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,6 +1,6 @@ pytz==2018.9 # https://github.com/stub42/pytz python-slugify==3.0.2 # https://github.com/un33k/python-slugify -Pillow==5.4.1 # https://github.com/python-pillow/Pillow +Pillow==6.0.0 # https://github.com/python-pillow/Pillow {%- if cookiecutter.use_compressor == "y" %} rcssmin==1.0.6{% if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin {%- endif %} From 8851ac13ef84d15f07d69ab107038956f79f5e9a Mon Sep 17 00:00:00 2001 From: Jelmert Date: Thu, 8 Nov 2018 11:14:58 +0100 Subject: [PATCH 076/126] Added the awscli container for uploading and downloading backups from and to Amazon S3 --- CONTRIBUTORS.rst | 2 ++ docs/docker-postgres-backups.rst | 8 +++++ .../compose/production/aws/Dockerfile | 9 ++++++ .../production/aws/maintenance/download | 24 +++++++++++++++ .../compose/production/aws/maintenance/upload | 30 +++++++++++++++++++ {{cookiecutter.project_slug}}/production.yml | 8 +++++ 6 files changed, 81 insertions(+) create mode 100644 {{cookiecutter.project_slug}}/compose/production/aws/Dockerfile create mode 100644 {{cookiecutter.project_slug}}/compose/production/aws/maintenance/download create mode 100644 {{cookiecutter.project_slug}}/compose/production/aws/maintenance/upload diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 154fa1ac..9486b3a0 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -114,6 +114,7 @@ Listed in alphabetical order. Irfan Ahmad `@erfaan`_ @erfaan Jan Van Bruggen `@jvanbrug`_ Jens Nilsson `@phiberjenz`_ + Jelmer Draaijer `@foarsitter`_ Jerome Leclanche `@jleclanche`_ @Adys Jimmy Gitonga `@afrowave`_ @afrowave John Cass `@jcass77`_ @cass_john @@ -231,6 +232,7 @@ Listed in alphabetical order. .. _@eriol: https://github.com/eriol .. _@eyadsibai: https://github.com/eyadsibai .. _@flyudvik: https://github.com/flyudvik +.. _@foarsitter: https://github.com/foarsitter .. _@garry-cairns: https://github.com/garry-cairns .. _@garrypolley: https://github.com/garrypolley .. _@goldhand: https://github.com/goldhand diff --git a/docs/docker-postgres-backups.rst b/docs/docker-postgres-backups.rst index c1a8a5e0..246ae403 100644 --- a/docs/docker-postgres-backups.rst +++ b/docs/docker-postgres-backups.rst @@ -85,3 +85,11 @@ You will see something like :: # ... ALTER TABLE SUCCESS: The 'my_project' database has been restored from the '/backups/backup_2018_03_13T09_05_07.sql.gz' backup. + + +Backup to Amazon S3 +---------------------------------- +For uploading your backups to Amazon S3 you can use the aws cli container. There is a upload command for uploading the postgres /backups directory recursively and there is a download command for downloading a specific backup. The default S3 environment variables are used. :: + + $ docker-compose -f production.yml run --rm awscli upload + $ docker-compose -f production.yml run --rm awscli download backup_2018_03_13T09_05_07.sql.gz diff --git a/{{cookiecutter.project_slug}}/compose/production/aws/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/aws/Dockerfile new file mode 100644 index 00000000..8282047b --- /dev/null +++ b/{{cookiecutter.project_slug}}/compose/production/aws/Dockerfile @@ -0,0 +1,9 @@ +FROM garland/aws-cli-docker:1.15.47 + +COPY ./compose/production/aws/maintenance /usr/local/bin/maintenance +COPY ./compose/production/postgres/maintenance/_sourced /usr/local/bin/maintenance/_sourced + +RUN chmod +x /usr/local/bin/maintenance/* + +RUN mv /usr/local/bin/maintenance/* /usr/local/bin \ + && rmdir /usr/local/bin/maintenance diff --git a/{{cookiecutter.project_slug}}/compose/production/aws/maintenance/download b/{{cookiecutter.project_slug}}/compose/production/aws/maintenance/download new file mode 100644 index 00000000..8d5ea091 --- /dev/null +++ b/{{cookiecutter.project_slug}}/compose/production/aws/maintenance/download @@ -0,0 +1,24 @@ +#!/bin/sh + +### Download a file from your Amazon S3 bucket to the postgres /backups folder +### +### Usage: +### $ docker-compose -f production.yml run --rm awscli <1> + +set -o errexit +set -o pipefail +set -o nounset + +working_dir="$(dirname ${0})" +source "${working_dir}/_sourced/constants.sh" +source "${working_dir}/_sourced/messages.sh" + +export AWS_ACCESS_KEY_ID="${DJANGO_AWS_ACCESS_KEY_ID}" +export AWS_SECRET_ACCESS_KEY="${DJANGO_AWS_SECRET_ACCESS_KEY}" +export AWS_STORAGE_BUCKET_NAME="${DJANGO_AWS_STORAGE_BUCKET_NAME}" + + +aws s3 cp s3://${AWS_STORAGE_BUCKET_NAME}${BACKUP_DIR_PATH}/${1} ${BACKUP_DIR_PATH}/${1} + +message_success "Finished downloading ${1}." + diff --git a/{{cookiecutter.project_slug}}/compose/production/aws/maintenance/upload b/{{cookiecutter.project_slug}}/compose/production/aws/maintenance/upload new file mode 100644 index 00000000..4a89dcb5 --- /dev/null +++ b/{{cookiecutter.project_slug}}/compose/production/aws/maintenance/upload @@ -0,0 +1,30 @@ +#!/bin/sh + +### Upload the /backups folder to Amazon S3 +### +### Usage: +### $ docker-compose -f production.yml run --rm awscli upload + +set -o errexit +set -o pipefail +set -o nounset + +working_dir="$(dirname ${0})" +source "${working_dir}/_sourced/constants.sh" +source "${working_dir}/_sourced/messages.sh" + +export AWS_ACCESS_KEY_ID="${DJANGO_AWS_ACCESS_KEY_ID}" +export AWS_SECRET_ACCESS_KEY="${DJANGO_AWS_SECRET_ACCESS_KEY}" +export AWS_STORAGE_BUCKET_NAME="${DJANGO_AWS_STORAGE_BUCKET_NAME}" + + +message_info "Upload the backups directory to S3 bucket {$AWS_STORAGE_BUCKET_NAME}" + +aws s3 cp ${BACKUP_DIR_PATH} s3://${AWS_STORAGE_BUCKET_NAME}${BACKUP_DIR_PATH} --recursive + +message_info "Cleaning the directory ${BACKUP_DIR_PATH}" + +rm -rf ${BACKUP_DIR_PATH}/* + +message_success "Finished uploading and cleaning." + diff --git a/{{cookiecutter.project_slug}}/production.yml b/{{cookiecutter.project_slug}}/production.yml index 88cf8773..a24ba829 100644 --- a/{{cookiecutter.project_slug}}/production.yml +++ b/{{cookiecutter.project_slug}}/production.yml @@ -65,3 +65,11 @@ services: command: /start-flower {%- endif %} + awscli: + build: + context: . + dockerfile: ./compose/production/aws/Dockerfile + env_file: + - ./.envs/.production/.django + volumes: + - production_postgres_data_backups:/backups From 27d806fab11734440cb97e987ea2886182fc3811 Mon Sep 17 00:00:00 2001 From: Jelmert Date: Fri, 23 Nov 2018 11:19:54 +0100 Subject: [PATCH 077/126] Typo --- docs/docker-postgres-backups.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docker-postgres-backups.rst b/docs/docker-postgres-backups.rst index 246ae403..6ccb7cf1 100644 --- a/docs/docker-postgres-backups.rst +++ b/docs/docker-postgres-backups.rst @@ -89,7 +89,7 @@ You will see something like :: Backup to Amazon S3 ---------------------------------- -For uploading your backups to Amazon S3 you can use the aws cli container. There is a upload command for uploading the postgres /backups directory recursively and there is a download command for downloading a specific backup. The default S3 environment variables are used. :: +For uploading your backups to Amazon S3 you can use the aws cli container. There is an upload command for uploading the postgres /backups directory recursively and there is a download command for downloading a specific backup. The default S3 environment variables are used. :: $ docker-compose -f production.yml run --rm awscli upload $ docker-compose -f production.yml run --rm awscli download backup_2018_03_13T09_05_07.sql.gz From d1bf4f48152ec00c3fbdd45888e4963e302f36e4 Mon Sep 17 00:00:00 2001 From: Jelmert Date: Tue, 2 Apr 2019 15:43:48 +0200 Subject: [PATCH 078/126] Added AWS_S3_REGION_NAME to production settings --- {{cookiecutter.project_slug}}/config/settings/production.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 3db964b6..236c6c9f 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -86,6 +86,8 @@ AWS_S3_OBJECT_PARAMETERS = { } # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_DEFAULT_ACL = None +# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings +AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None) # STATIC # ------------------------ From 7e23327fe2c705b6e858bd6fbbc7b40e3b2e2e74 Mon Sep 17 00:00:00 2001 From: Jelmert Date: Tue, 2 Apr 2019 15:45:58 +0200 Subject: [PATCH 079/126] Added DJANG_AWS_S3_REGION_NAME to settings docs --- docs/settings.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/settings.rst b/docs/settings.rst index 705add87..212527cf 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -44,6 +44,7 @@ CELERY_BROKER_URL CELERY_BROKER_URL auto w/ Dock 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 +DJANGO_AWS_S3_REGION_NAME AWS_S3_REGION_NAME n/a None SENTRY_DSN SENTRY_DSN n/a raises error DJANGO_SENTRY_LOG_LEVEL SENTRY_LOG_LEVEL n/a logging.INFO MAILGUN_API_KEY MAILGUN_ACCESS_KEY n/a raises error From d8271fae21cd8a15e8ec40cdd8825eb4081d208f Mon Sep 17 00:00:00 2001 From: Jelmert Date: Tue, 2 Apr 2019 15:47:18 +0200 Subject: [PATCH 080/126] Added myself to CONTRIBUTORS.rst --- CONTRIBUTORS.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 154fa1ac..9486b3a0 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -114,6 +114,7 @@ Listed in alphabetical order. Irfan Ahmad `@erfaan`_ @erfaan Jan Van Bruggen `@jvanbrug`_ Jens Nilsson `@phiberjenz`_ + Jelmer Draaijer `@foarsitter`_ Jerome Leclanche `@jleclanche`_ @Adys Jimmy Gitonga `@afrowave`_ @afrowave John Cass `@jcass77`_ @cass_john @@ -231,6 +232,7 @@ Listed in alphabetical order. .. _@eriol: https://github.com/eriol .. _@eyadsibai: https://github.com/eyadsibai .. _@flyudvik: https://github.com/flyudvik +.. _@foarsitter: https://github.com/foarsitter .. _@garry-cairns: https://github.com/garry-cairns .. _@garrypolley: https://github.com/garrypolley .. _@goldhand: https://github.com/goldhand From 1d420157c10f0c25839e186b0c1b13f6eb35fe1f Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 2 Apr 2019 15:10:14 +0100 Subject: [PATCH 081/126] Revert accidental commit --- tests/test_docker.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/test_docker.sh b/tests/test_docker.sh index 018ad85f..55771c14 100755 --- a/tests/test_docker.sh +++ b/tests/test_docker.sh @@ -16,9 +16,17 @@ cd .cache/docker cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y $@ cd my_awesome_project -# run migrations -docker-compose -f local.yml run django python manage.py migrate +# run the project's type checks +docker-compose -f local.yml run django mypy my_awesome_project -# view backups -docker-compose -f local.yml exec postgres backups +# Run black with --check option +docker-compose -f local.yml run django black --check --diff --exclude 'migrations' ./ +# run the project's tests +docker-compose -f local.yml run django pytest + +# return non-zero status code if there are migrations that have not been created +docker-compose -f local.yml run django python manage.py makemigrations --dry-run --check || { echo "ERROR: there were changes in the models, but migration listed above have not been created and are not saved in version control"; exit 1; } + +# Test support for translations +docker-compose -f local.yml run django python manage.py makemessages From f6e84cb2115cce1e2017c3011c0303adc915eaab Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 2 Apr 2019 19:11:47 +0100 Subject: [PATCH 082/126] Upgrade Django to 2.1.8 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 9d4aec7d..6c70c367 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -18,7 +18,7 @@ flower==0.9.3 # https://github.com/mher/flower # Django # ------------------------------------------------------------------------------ -django==2.0.13 # pyup: < 2.1 # https://www.djangoproject.com/ +django==2.1.8 # pyup: < 2.2 # 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.39.1 # https://github.com/pennersr/django-allauth From 57dd157c4ae604c58bd754fb9d769f8081eedbbf Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 2 Apr 2019 19:37:12 +0100 Subject: [PATCH 083/126] Remove deprecated password hasher --- {{cookiecutter.project_slug}}/config/settings/base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py index f8d22377..026c88cf 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -109,7 +109,6 @@ PASSWORD_HASHERS = [ "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", - "django.contrib.auth.hashers.BCryptPasswordHasher", ] # https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ From dd284bc8c998cf43c9ea8b4c52b10280c43628c6 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 2 Apr 2019 19:37:59 +0100 Subject: [PATCH 084/126] Remove Postgres 9.3 as it's not supported by Django 2.1 --- cookiecutter.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cookiecutter.json b/cookiecutter.json index b5dda0c7..11e4456f 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -25,8 +25,7 @@ "10.1", "9.6", "9.5", - "9.4", - "9.3" + "9.4" ], "js_task_runner": [ "None", From 2dcbaca3ee292d3dbcc0271f9add1bd7b3361037 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 2 Apr 2019 19:38:23 +0100 Subject: [PATCH 085/126] Update documentation --- README.rst | 25 ++++++++++++------------ docs/project-generation-options.rst | 15 +++++++------- {{cookiecutter.project_slug}}/README.rst | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/README.rst b/README.rst index 2c037e51..00215092 100644 --- a/README.rst +++ b/README.rst @@ -36,10 +36,10 @@ production-ready Django projects quickly. Features --------- -* For Django 2.0 +* For Django 2.1 * Works with Python 3.6 * Renders Django projects with 100% starting test coverage -* Twitter Bootstrap_ v4.1.1 (`maintained Foundation fork`_ also available) +* Twitter Bootstrap_ v4 (`maintained Foundation fork`_ also available) * 12-Factor_ based settings via django-environ_ * Secure by default. We believe in SSL. * Optimized development and production settings @@ -89,8 +89,8 @@ Constraints ----------- * Only maintained 3rd party libraries are used. -* Uses PostgreSQL everywhere (9.2+) -* Environment variables for configuration (This won't work with Apache/mod_wsgi except on AWS ELB). +* Uses PostgreSQL everywhere (9.4 - 10.5) +* Environment variables for configuration (This won't work with Apache/mod_wsgi). Support this Project! ---------------------- @@ -169,14 +169,15 @@ Answer the prompts with your own desired options_. For example:: use_heroku [n]: y use_compressor [n]: y Select postgresql_version: - 1 - 10.3 - 2 - 10.2 - 3 - 10.1 - 4 - 9.6 - 5 - 9.5 - 6 - 9.4 - 7 - 9.3 - Choose from 1, 2, 3, 4 [1]: 1 + 1 - 10.5 + 2 - 10.4 + 3 - 10.3 + 4 - 10.2 + 5 - 10.1 + 6 - 9.6 + 7 - 9.5 + 8 - 9.4 + Choose from 1, 2, 3, 4, 5, 6, 7, 8 [1]: 1 Select js_task_runner: 1 - None 2 - Gulp diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index a5483797..f9824a6d 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -49,13 +49,14 @@ use_docker: postgresql_version: Select a PostgreSQL_ version to use. The choices are: - 1. 10.3 - 2. 10.2 - 3. 10.1 - 4. 9.6 - 5. 9.5 - 6. 9.4 - 7. 9.3 + 1. 10.5 + 2. 10.4 + 3. 10.3 + 4. 10.2 + 5. 10.1 + 6. 9.6 + 7. 9.5 + 8. 9.4 js_task_runner: Select a JavaScript task runner. The choices are: diff --git a/{{cookiecutter.project_slug}}/README.rst b/{{cookiecutter.project_slug}}/README.rst index 6ef3b63c..b9dbf218 100644 --- a/{{cookiecutter.project_slug}}/README.rst +++ b/{{cookiecutter.project_slug}}/README.rst @@ -159,7 +159,7 @@ Custom Bootstrap Compilation ^^^^^^ The generated CSS is set up with automatic Bootstrap recompilation with variables of your choice. -Bootstrap v4.1.1 is installed using npm and customised by tweaking your variables in ``static/sass/custom_bootstrap_vars``. +Bootstrap v4 is installed using npm and customised by tweaking your variables in ``static/sass/custom_bootstrap_vars``. You can find a list of available variables `in the bootstrap source`_, or get explanations on them in the `Bootstrap docs`_. From e7115fcee93b6d3d0f82a97bb9d97ab2fe28efc9 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Wed, 3 Apr 2019 12:00:30 +0100 Subject: [PATCH 086/126] Update werkzeug from 0.15.1 to 0.15.2 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 028886b0..01bb6d2f 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -1,6 +1,6 @@ -r ./base.txt -Werkzeug==0.15.1 # https://github.com/pallets/werkzeug +Werkzeug==0.15.2 # https://github.com/pallets/werkzeug ipdb==0.12 # https://github.com/gotcha/ipdb Sphinx==2.0.0 # https://github.com/sphinx-doc/sphinx {%- if cookiecutter.use_docker == 'y' %} From 0aafad16dd5f7d93f02dee9cb268dee9fa8ce2b0 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 3 Apr 2019 10:24:10 -0700 Subject: [PATCH 087/126] Update tox from 3.8.4 to 3.8.6 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index aebe0e54..c38f0650 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ -tox==3.8.4 +tox==3.8.6 pytest==4.4.0 pytest_cases==1.5.1 pytest-cookies==0.3.0 From c80bcb8932856c405cb01862340a18ffe2a90d06 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 3 Apr 2019 10:24:15 -0700 Subject: [PATCH 088/126] Update pytest_cases from 1.5.1 to 1.6.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index aebe0e54..efeb48f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,6 +11,6 @@ flake8==3.7.6 # ------------------------------------------------------------------------------ tox==3.8.4 pytest==4.4.0 -pytest_cases==1.5.1 +pytest_cases==1.6.1 pytest-cookies==0.3.0 pyyaml==5.1 From ea749071c2b681b5b7a576eb62279d8c8c53f6dd Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 4 Apr 2019 12:00:30 +0100 Subject: [PATCH 089/126] Update psycopg2-binary from 2.7.7 to 2.8 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 01bb6d2f..05ddb714 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -6,7 +6,7 @@ Sphinx==2.0.0 # 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.7 # https://github.com/psycopg/psycopg2 +psycopg2-binary==2.8 # https://github.com/psycopg/psycopg2 {%- endif %} # Testing From 63f5ad028039da2ad52b659046e87f66de571686 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 4 Apr 2019 12:00:33 +0100 Subject: [PATCH 090/126] Update mypy from 0.670 to 0.700 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 01bb6d2f..7e1cc25a 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -11,7 +11,7 @@ psycopg2-binary==2.7.7 # https://github.com/psycopg/psycopg2 # Testing # ------------------------------------------------------------------------------ -mypy==0.670 # https://github.com/python/mypy +mypy==0.700 # https://github.com/python/mypy pytest==4.4.0 # https://github.com/pytest-dev/pytest pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar From b9c5ca2b86dd5c347d8317fe59597a4a9d59aa15 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Thu, 4 Apr 2019 15:03:49 +0200 Subject: [PATCH 091/126] Also update psycopg2 no-binary --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 05ddb714..2d7e3ba1 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -4,7 +4,7 @@ Werkzeug==0.15.2 # https://github.com/pallets/werkzeug ipdb==0.12 # https://github.com/gotcha/ipdb Sphinx==2.0.0 # https://github.com/sphinx-doc/sphinx {%- if cookiecutter.use_docker == 'y' %} -psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 +psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 {%- else %} psycopg2-binary==2.8 # https://github.com/psycopg/psycopg2 {%- endif %} From b30b9795d2f142bd06bf8e431105cf97f68163bd Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Thu, 4 Apr 2019 15:04:57 +0200 Subject: [PATCH 092/126] Update psycopg2 to 2.8 in production --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 035cefd7..5a40f07a 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -3,7 +3,7 @@ -r ./base.txt gunicorn==19.9.0 # https://github.com/benoitc/gunicorn -psycopg2==2.7.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 +psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 {%- if cookiecutter.use_whitenoise == 'n' %} Collectfast==0.6.2 # https://github.com/antonagestam/collectfast {%- endif %} From cad0b7765878fdb2f8b19230d6ce9a52f3143c07 Mon Sep 17 00:00:00 2001 From: anuj Date: Tue, 2 Apr 2019 11:43:31 +0530 Subject: [PATCH 093/126] Added support for GCE Media storage --- cookiecutter.json | 4 ++++ .../.envs/.production/.django | 9 ++++++-- .../config/settings/production.py | 23 ++++++++++++------- .../requirements/production.txt | 4 ++++ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/cookiecutter.json b/cookiecutter.json index b5dda0c7..eabf7d14 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -32,6 +32,10 @@ "None", "Gulp" ], + "cloud_provider": [ + "AWS", + "GCE" + ], "custom_bootstrap_compilation": "n", "use_compressor": "n", "use_celery": "n", diff --git a/{{cookiecutter.project_slug}}/.envs/.production/.django b/{{cookiecutter.project_slug}}/.envs/.production/.django index 4175f894..a938ada6 100644 --- a/{{cookiecutter.project_slug}}/.envs/.production/.django +++ b/{{cookiecutter.project_slug}}/.envs/.production/.django @@ -16,13 +16,18 @@ DJANGO_SECURE_SSL_REDIRECT=False MAILGUN_API_KEY= DJANGO_SERVER_EMAIL= MAILGUN_DOMAIN= - +{% if cookiecutter.cloud_provider == 'AWS' %} # AWS # ------------------------------------------------------------------------------ DJANGO_AWS_ACCESS_KEY_ID= DJANGO_AWS_SECRET_ACCESS_KEY= DJANGO_AWS_STORAGE_BUCKET_NAME= - +{% elif cookiecutter.cloud_provider == 'GCE' %} +# GCE +# ------------------------------------------------------------------------------ +GOOGLE_APPLICATION_CREDENTIALS= +DJANGO_GCE_STORAGE_BUCKET_NAME= +{% endif %} # django-allauth # ------------------------------------------------------------------------------ DJANGO_ACCOUNT_ALLOW_REGISTRATION=True diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 236c6c9f..26fa6294 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -69,7 +69,8 @@ SECURE_CONTENT_TYPE_NOSNIFF = env.bool( # STORAGES # ------------------------------------------------------------------------------ # https://django-storages.readthedocs.io/en/latest/#installation -INSTALLED_APPS += ["storages"] # noqa F405 +INSTALLED_APPS += ['storages'] # noqa F405 +{% if cookiecutter.cloud_provider == 'AWS' %} # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_ACCESS_KEY_ID = env("DJANGO_AWS_ACCESS_KEY_ID") # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings @@ -88,22 +89,25 @@ AWS_S3_OBJECT_PARAMETERS = { AWS_DEFAULT_ACL = None # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None) +{% elif cookiecutter.cloud_provider == 'GCE' %} +DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage' +GS_BUCKET_NAME = env('DJANGO_GCE_STORAGE_BUCKET_NAME') +GS_DEFAULT_ACL = 'publicRead' +{% endif %} # STATIC # ------------------------ {% if cookiecutter.use_whitenoise == 'y' -%} STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" -{%- else %} -STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage" -STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/" +{%- endif -%} +{%- if cookiecutter.cloud_provider == 'AWS' %} +STATICFILES_STORAGE = 'config.settings.production.StaticRootS3Boto3Storage' +STATIC_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/' {%- endif %} # MEDIA # ------------------------------------------------------------------------------ -{% if cookiecutter.use_whitenoise == 'y' -%} -DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" -MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/" -{%- else %} +{%- if cookiecutter.cloud_provider == 'AWS' %} # region http://stackoverflow.com/questions/10390244/ # Full-fledge class: https://stackoverflow.com/a/18046120/104731 from storages.backends.s3boto3 import S3Boto3Storage # noqa E402 @@ -121,6 +125,9 @@ class MediaRootS3Boto3Storage(S3Boto3Storage): # endregion DEFAULT_FILE_STORAGE = "config.settings.production.MediaRootS3Boto3Storage" MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/" +{%- elif cookiecutter.cloud_provider == 'GCE' %} +MEDIA_URL = 'https://storage.googleapis.com/{}/'.format(GS_BUCKET_NAME) +MEDIA_ROOT = 'https://storage.googleapis.com/{}/'.format(GS_BUCKET_NAME) {%- endif %} # TEMPLATES diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 5a40f07a..b1758194 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -13,5 +13,9 @@ sentry-sdk==0.7.9 # https://github.com/getsentry/sentry-python # Django # ------------------------------------------------------------------------------ +{%- if cookiecutter.cloud_provider == 'AWS' %} django-storages[boto3]==1.7.1 # https://github.com/jschneier/django-storages +{%- elif cookiecutter.cloud_provider == 'GCE' %} +django-storages[google]==1.7.1 # https://github.com/jschneier/django-storages +{%- endif %} django-anymail[mailgun]==6.0 # https://github.com/anymail/django-anymail From 749920e81cd4e382b06cd1bcb32a17201fe44853 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Sat, 6 Apr 2019 13:00:29 +0200 Subject: [PATCH 094/126] Update pytest_cases from 1.6.1 to 1.6.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2b2c55f3..25b0135b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,6 +11,6 @@ flake8==3.7.6 # ------------------------------------------------------------------------------ tox==3.8.6 pytest==4.4.0 -pytest_cases==1.6.1 +pytest_cases==1.6.2 pytest-cookies==0.3.0 pyyaml==5.1 From c582ac48ec5bc61a849b3ceb6d5d4b6f0c854f7c Mon Sep 17 00:00:00 2001 From: browniebroke Date: Sat, 6 Apr 2019 13:00:32 +0200 Subject: [PATCH 095/126] Update sentry-sdk from 0.7.9 to 0.7.10 --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 5a40f07a..ea4b376f 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 Collectfast==0.6.2 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==0.7.9 # https://github.com/getsentry/sentry-python +sentry-sdk==0.7.10 # https://github.com/getsentry/sentry-python {%- endif %} # Django From b5e030b78439c1118d8e64c1ee582bcb6595059e Mon Sep 17 00:00:00 2001 From: anuj Date: Sun, 7 Apr 2019 00:34:22 +0530 Subject: [PATCH 096/126] Corrected quotes, added parameter in tests --- tests/test_cookiecutter_generation.py | 4 ++++ .../config/settings/production.py | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index 36395627..17375b1c 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -11,6 +11,7 @@ PATTERN = "{{(\s?cookiecutter)[.](.*?)}}" RE_OBJ = re.compile(PATTERN) YN_CHOICES = ["y", "n"] +CLOUD_CHOICES = ["AWS", "GCE"] @pytest.fixture @@ -35,6 +36,7 @@ def context(): @pytest.mark.parametrize("use_sentry", YN_CHOICES, ids=lambda yn: f"sentry:{yn}") @pytest.mark.parametrize("use_compressor", YN_CHOICES, ids=lambda yn: f"cmpr:{yn}") @pytest.mark.parametrize("use_whitenoise", YN_CHOICES, ids=lambda yn: f"wnoise:{yn}") +@pytest.mark.parametrize("cloud_provider", CLOUD_CHOICES, ids=lambda yn: f"cloud:{yn}") def context_combination( windows, use_docker, @@ -43,6 +45,7 @@ def context_combination( use_sentry, use_compressor, use_whitenoise, + cloud_provider, ): """Fixture that parametrize the function where it's used.""" return { @@ -53,6 +56,7 @@ def context_combination( "use_mailhog": use_mailhog, "use_sentry": use_sentry, "use_whitenoise": use_whitenoise, + "cloud_provider": cloud_provider, } diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 26fa6294..61f90104 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -69,7 +69,7 @@ SECURE_CONTENT_TYPE_NOSNIFF = env.bool( # STORAGES # ------------------------------------------------------------------------------ # https://django-storages.readthedocs.io/en/latest/#installation -INSTALLED_APPS += ['storages'] # noqa F405 +INSTALLED_APPS += ["storages"] # noqa F405 {% if cookiecutter.cloud_provider == 'AWS' %} # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_ACCESS_KEY_ID = env("DJANGO_AWS_ACCESS_KEY_ID") @@ -90,9 +90,9 @@ AWS_DEFAULT_ACL = None # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None) {% elif cookiecutter.cloud_provider == 'GCE' %} -DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage' -GS_BUCKET_NAME = env('DJANGO_GCE_STORAGE_BUCKET_NAME') -GS_DEFAULT_ACL = 'publicRead' +DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorage" +GS_BUCKET_NAME = env("DJANGO_GCE_STORAGE_BUCKET_NAME") +GS_DEFAULT_ACL = "publicRead" {% endif %} # STATIC @@ -101,8 +101,8 @@ GS_DEFAULT_ACL = 'publicRead' STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" {%- endif -%} {%- if cookiecutter.cloud_provider == 'AWS' %} -STATICFILES_STORAGE = 'config.settings.production.StaticRootS3Boto3Storage' -STATIC_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/' +STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage" +STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/" {%- endif %} # MEDIA @@ -126,8 +126,8 @@ class MediaRootS3Boto3Storage(S3Boto3Storage): DEFAULT_FILE_STORAGE = "config.settings.production.MediaRootS3Boto3Storage" MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/" {%- elif cookiecutter.cloud_provider == 'GCE' %} -MEDIA_URL = 'https://storage.googleapis.com/{}/'.format(GS_BUCKET_NAME) -MEDIA_ROOT = 'https://storage.googleapis.com/{}/'.format(GS_BUCKET_NAME) +MEDIA_URL = "https://storage.googleapis.com/{}/".format(GS_BUCKET_NAME) +MEDIA_ROOT = "https://storage.googleapis.com/{}/".format(GS_BUCKET_NAME) {%- endif %} # TEMPLATES From 2b141e646434396dbb40a2accd224c42dc105ce3 Mon Sep 17 00:00:00 2001 From: anuj Date: Sun, 7 Apr 2019 00:54:46 +0530 Subject: [PATCH 097/126] Add support for GCE static --- {{cookiecutter.project_slug}}/config/settings/production.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 61f90104..4adbdb9c 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -103,6 +103,8 @@ STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" {%- if cookiecutter.cloud_provider == 'AWS' %} STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage" STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/" +{%- elif cookiecutter.cloud_provider == 'GCE' %} +STATIC_URL = "https://storage.googleapis.com/{}/static".format(GS_BUCKET_NAME) {%- endif %} # MEDIA @@ -126,8 +128,8 @@ class MediaRootS3Boto3Storage(S3Boto3Storage): DEFAULT_FILE_STORAGE = "config.settings.production.MediaRootS3Boto3Storage" MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/" {%- elif cookiecutter.cloud_provider == 'GCE' %} -MEDIA_URL = "https://storage.googleapis.com/{}/".format(GS_BUCKET_NAME) -MEDIA_ROOT = "https://storage.googleapis.com/{}/".format(GS_BUCKET_NAME) +MEDIA_URL = "https://storage.googleapis.com/{}/media".format(GS_BUCKET_NAME) +MEDIA_ROOT = "https://storage.googleapis.com/{}/media".format(GS_BUCKET_NAME) {%- endif %} # TEMPLATES From 020933d336c09a7946edd69c92c2562f085c2ff2 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Tue, 9 Apr 2019 13:00:39 +0200 Subject: [PATCH 098/126] Update sphinx from 2.0.0 to 2.0.1 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index eb81e7d0..1c90cd84 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -2,7 +2,7 @@ Werkzeug==0.15.2 # https://github.com/pallets/werkzeug ipdb==0.12 # https://github.com/gotcha/ipdb -Sphinx==2.0.0 # https://github.com/sphinx-doc/sphinx +Sphinx==2.0.1 # https://github.com/sphinx-doc/sphinx {%- if cookiecutter.use_docker == 'y' %} psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 {%- else %} From 6d906721fc74593c56b70a10ad9804c5ea6afb32 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Wed, 10 Apr 2019 13:00:32 +0200 Subject: [PATCH 099/126] Update pytz from 2018.9 to 2019.1 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 9d4aec7d..39bec2d4 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,4 +1,4 @@ -pytz==2018.9 # https://github.com/stub42/pytz +pytz==2019.1 # https://github.com/stub42/pytz python-slugify==3.0.2 # https://github.com/un33k/python-slugify Pillow==6.0.0 # https://github.com/python-pillow/Pillow {%- if cookiecutter.use_compressor == "y" %} From 56aa332e0146ef94306ebac3f0fdacbd64fcb4fc Mon Sep 17 00:00:00 2001 From: Vlad Date: Sun, 14 Apr 2019 11:43:05 -0500 Subject: [PATCH 100/126] Documented Google Cloud Storage integration as an alternative to AWS S3 --- README.rst | 8 ++++++-- docs/project-generation-options.rst | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 2c037e51..fccbdaf9 100644 --- a/README.rst +++ b/README.rst @@ -47,7 +47,7 @@ Features * Comes with custom user model ready to go * Optional custom static build using Gulp and livereload * Send emails via Anymail_ (using Mailgun_ by default, but switchable) -* Media storage using Amazon S3 +* Media storage using Amazon S3 or Google Cloud Storage * Docker support using docker-compose_ for development and production (using Traefik_ with LetsEncrypt_ support) * Procfile_ for deploying to Heroku * Instructions for deploying to PythonAnywhere_ @@ -62,7 +62,7 @@ Optional Integrations *These features can be enabled during initial project setup.* -* Serve static files from Amazon S3 or Whitenoise_ +* Serve static files from Amazon S3, Google Cloud Storage or Whitenoise_ * Configuration for Celery_ and Flower_ (the latter in Docker setup only) * Integration with MailHog_ for local email testing * Integration with Sentry_ for error logging @@ -181,6 +181,10 @@ Answer the prompts with your own desired options_. For example:: 1 - None 2 - Gulp Choose from 1, 2 [1]: 1 + Select cloud_provider: + 1 - AWS + 2 - GCS + Choose from 1, 2 [1]: 1 custom_bootstrap_compilation [n]: n Select open_source_license: 1 - MIT diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index a5483797..82e9edc0 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -63,6 +63,12 @@ js_task_runner: 1. None 2. Gulp_ +cloud_provider: + Select a cloud provider for static files. The choices are: + + 1. AWS_ + 2. GCS_ + custom_bootstrap_compilation: Indicates whether the project should support Bootstrap recompilation via the selected JavaScript task runner's task. This can be useful From 7c8a473460f6c90a9773357aaec955b4591f5f65 Mon Sep 17 00:00:00 2001 From: Vlad Date: Sun, 14 Apr 2019 11:57:48 -0500 Subject: [PATCH 101/126] Updated settings.rst to reflect new GS env variable --- docs/settings.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/settings.rst b/docs/settings.rst index 212527cf..dd698a0d 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -45,6 +45,7 @@ DJANGO_AWS_ACCESS_KEY_ID AWS_ACCESS_KEY_ID n/a 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 DJANGO_AWS_S3_REGION_NAME AWS_S3_REGION_NAME n/a None +DJANGO_GCE_STORAGE_BUCKET_NAME GS_BUCKET_NAME n/a raises error SENTRY_DSN SENTRY_DSN n/a raises error DJANGO_SENTRY_LOG_LEVEL SENTRY_LOG_LEVEL n/a logging.INFO MAILGUN_API_KEY MAILGUN_ACCESS_KEY n/a raises error From c041453bef94930c658edffe3f009b799d459a7d Mon Sep 17 00:00:00 2001 From: Vlad Date: Sun, 14 Apr 2019 12:07:37 -0500 Subject: [PATCH 102/126] Updated project-generation-options.rst to provide helpful links in case a user needs to decide between AWS s3 and GCS and added myself to contributors.rst --- CONTRIBUTORS.rst | 2 ++ docs/project-generation-options.rst | 3 +++ 2 files changed, 5 insertions(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 9486b3a0..ded1606b 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -177,6 +177,7 @@ Listed in alphabetical order. Travis McNeill `@Travistock`_ @tavistock_esq Tubo Shi `@Tubo`_ Umair Ashraf `@umrashrf`_ @fabumair + Vlad Doster `@vladdoster`_ Vitaly Babiy Vivian Guillen `@viviangb`_ Will Farley `@goldhand`_ @g01dhand @@ -315,6 +316,7 @@ Listed in alphabetical order. .. _@mrcoles: https://github.com/mrcoles .. _@ericgroom: https://github.com/ericgroom .. _@hanaquadara: https://github.com/hanaquadara +.. _@vladdoster: https://github.com/vladdoster Special Thanks ~~~~~~~~~~~~~~ diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index 82e9edc0..470ef949 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -121,6 +121,9 @@ debug: .. _Gulp: https://github.com/gulpjs/gulp +.. _AWS: https://aws.amazon.com/s3/ +.. _GCS: https://cloud.google.com/storage/ + .. _Django Compressor: https://github.com/django-compressor/django-compressor .. _Celery: https://github.com/celery/celery From 9137bb561fc1a7fbe83a6ca61e5c0fffe0c10146 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Tue, 16 Apr 2019 12:00:29 +0100 Subject: [PATCH 103/126] Update pytest from 4.4.0 to 4.4.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 25b0135b..cfd0c847 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ tox==3.8.6 -pytest==4.4.0 +pytest==4.4.1 pytest_cases==1.6.2 pytest-cookies==0.3.0 pyyaml==5.1 From 026dd6ed575d53d2af49b0878b8080b793c388c0 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Tue, 16 Apr 2019 12:00:30 +0100 Subject: [PATCH 104/126] Update pytest from 4.4.0 to 4.4.1 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 1c90cd84..60c68dd1 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -12,7 +12,7 @@ psycopg2-binary==2.8 # https://github.com/psycopg/psycopg2 # Testing # ------------------------------------------------------------------------------ mypy==0.700 # https://github.com/python/mypy -pytest==4.4.0 # https://github.com/pytest-dev/pytest +pytest==4.4.1 # https://github.com/pytest-dev/pytest pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar # Code quality From f6cac35b8743407b788ea98b8b2c0444ed25df04 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 16 Apr 2019 11:23:41 -0500 Subject: [PATCH 105/126] Update docs/project-generation-options.rst Clearer diction describing cloud provider roles Co-Authored-By: vladdoster --- docs/project-generation-options.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index 470ef949..c9b3dff8 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -64,7 +64,7 @@ js_task_runner: 2. Gulp_ cloud_provider: - Select a cloud provider for static files. The choices are: + Select a cloud provider for static & media files. The choices are: 1. AWS_ 2. GCS_ From cd13ab4c823e3c9619c9deac5ca368b9af477a9a Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 16 Apr 2019 11:30:22 -0500 Subject: [PATCH 106/126] Update docs/settings.rst Documented GOOGLE_APPLICATION_CREDENTIALS env var Co-Authored-By: vladdoster --- docs/settings.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/settings.rst b/docs/settings.rst index dd698a0d..1830a47c 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -46,6 +46,7 @@ DJANGO_AWS_SECRET_ACCESS_KEY AWS_SECRET_ACCESS_KEY n/a DJANGO_AWS_STORAGE_BUCKET_NAME AWS_STORAGE_BUCKET_NAME n/a raises error DJANGO_AWS_S3_REGION_NAME AWS_S3_REGION_NAME n/a None DJANGO_GCE_STORAGE_BUCKET_NAME GS_BUCKET_NAME n/a raises error +GOOGLE_APPLICATION_CREDENTIALS n/a n/a raises error SENTRY_DSN SENTRY_DSN n/a raises error DJANGO_SENTRY_LOG_LEVEL SENTRY_LOG_LEVEL n/a logging.INFO MAILGUN_API_KEY MAILGUN_ACCESS_KEY n/a raises error From 6f2a652c2b5be918a67294522e7fdeb04924b539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20C=2E=20Barrionuevo=20da=20Luz?= Date: Tue, 16 Apr 2019 19:42:57 -0300 Subject: [PATCH 107/126] update PostgreSQL versions in the example --- README.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index fccbdaf9..5a0fc5fb 100644 --- a/README.rst +++ b/README.rst @@ -169,13 +169,15 @@ Answer the prompts with your own desired options_. For example:: use_heroku [n]: y use_compressor [n]: y Select postgresql_version: - 1 - 10.3 - 2 - 10.2 - 3 - 10.1 - 4 - 9.6 - 5 - 9.5 - 6 - 9.4 - 7 - 9.3 + 1 - 10.5 + 2 - 10.4 + 3 - 10.3 + 4 - 10.2 + 5 - 10.1 + 6 - 9.6 + 7 - 9.5 + 8 - 9.4 + 9 - 9.3 Choose from 1, 2, 3, 4 [1]: 1 Select js_task_runner: 1 - None From 4d8e3c8c137a9bd2e54a4a408d27ee0e65e9f57e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20C=2E=20Barrionuevo=20da=20Luz?= Date: Tue, 16 Apr 2019 20:24:05 -0300 Subject: [PATCH 108/126] update "description" in the example --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 5a0fc5fb..91fbe3ef 100644 --- a/README.rst +++ b/README.rst @@ -155,7 +155,7 @@ Answer the prompts with your own desired options_. For example:: project_slug [reddit_clone]: reddit author_name [Daniel Roy Greenfeld]: Daniel Greenfeld email [you@example.com]: pydanny@gmail.com - description [A short description of the project.]: A reddit clone. + description [Behold My Awesome Project!]: A reddit clone. domain_name [example.com]: myreddit.com version [0.1.0]: 0.0.1 timezone [UTC]: America/Los_Angeles From 93d5426cb4cf63122364fd52da97296d40d9d78a Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Wed, 17 Apr 2019 08:37:45 +0100 Subject: [PATCH 109/126] Small updates in the READMEs --- README.rst | 6 +++--- {{cookiecutter.project_slug}}/README.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 91fbe3ef..9e76d802 100644 --- a/README.rst +++ b/README.rst @@ -39,7 +39,7 @@ Features * For Django 2.0 * Works with Python 3.6 * Renders Django projects with 100% starting test coverage -* Twitter Bootstrap_ v4.1.1 (`maintained Foundation fork`_ also available) +* Twitter Bootstrap_ v4 (`maintained Foundation fork`_ also available) * 12-Factor_ based settings via django-environ_ * Secure by default. We believe in SSL. * Optimized development and production settings @@ -51,7 +51,7 @@ Features * Docker support using docker-compose_ for development and production (using Traefik_ with LetsEncrypt_ support) * Procfile_ for deploying to Heroku * Instructions for deploying to PythonAnywhere_ -* Run tests with unittest or py.test +* Run tests with unittest or pytest * Customizable PostgreSQL version .. _`maintained Foundation fork`: https://github.com/Parbhat/cookiecutter-django-foundation @@ -90,7 +90,7 @@ Constraints * Only maintained 3rd party libraries are used. * Uses PostgreSQL everywhere (9.2+) -* Environment variables for configuration (This won't work with Apache/mod_wsgi except on AWS ELB). +* Environment variables for configuration (This won't work with Apache/mod_wsgi). Support this Project! ---------------------- diff --git a/{{cookiecutter.project_slug}}/README.rst b/{{cookiecutter.project_slug}}/README.rst index 6ef3b63c..b9dbf218 100644 --- a/{{cookiecutter.project_slug}}/README.rst +++ b/{{cookiecutter.project_slug}}/README.rst @@ -159,7 +159,7 @@ Custom Bootstrap Compilation ^^^^^^ The generated CSS is set up with automatic Bootstrap recompilation with variables of your choice. -Bootstrap v4.1.1 is installed using npm and customised by tweaking your variables in ``static/sass/custom_bootstrap_vars``. +Bootstrap v4 is installed using npm and customised by tweaking your variables in ``static/sass/custom_bootstrap_vars``. You can find a list of available variables `in the bootstrap source`_, or get explanations on them in the `Bootstrap docs`_. From 352be0eec947cff860ddd289cbe05ba709bbf03b Mon Sep 17 00:00:00 2001 From: browniebroke Date: Wed, 17 Apr 2019 12:00:31 +0100 Subject: [PATCH 110/126] Update mypy from 0.700 to 0.701 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 60c68dd1..a2f72eda 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -11,7 +11,7 @@ psycopg2-binary==2.8 # https://github.com/psycopg/psycopg2 # Testing # ------------------------------------------------------------------------------ -mypy==0.700 # https://github.com/python/mypy +mypy==0.701 # https://github.com/python/mypy pytest==4.4.1 # https://github.com/pytest-dev/pytest pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar From 5a3d9050a4d6274f206bb2c2979d89188feaebcf Mon Sep 17 00:00:00 2001 From: browniebroke Date: Wed, 17 Apr 2019 12:00:36 +0100 Subject: [PATCH 111/126] Update pylint-django from 2.0.6 to 2.0.7 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 60c68dd1..d0e909e5 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -20,7 +20,7 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar flake8==3.7.5 # https://github.com/PyCQA/flake8 coverage==4.5.3 # https://github.com/nedbat/coveragepy black==19.3b0 # https://github.com/ambv/black -pylint-django==2.0.6 # https://github.com/PyCQA/pylint-django +pylint-django==2.0.7 # https://github.com/PyCQA/pylint-django {%- if cookiecutter.use_celery == 'y' %} pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery {%- endif %} From a1692ef5410b98583def7703d156305800d9e95c Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 17 Apr 2019 19:13:06 -0700 Subject: [PATCH 112/126] Update tox from 3.8.6 to 3.9.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cfd0c847..ea10eaa5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ -tox==3.8.6 +tox==3.9.0 pytest==4.4.1 pytest_cases==1.6.2 pytest-cookies==0.3.0 From 113f1ed53095a7439d40e10d625019eab248e122 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 18 Apr 2019 12:00:29 +0100 Subject: [PATCH 113/126] Update pylint-django from 2.0.7 to 2.0.8 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index bd2d58ad..5d85b6ff 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -20,7 +20,7 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar flake8==3.7.5 # https://github.com/PyCQA/flake8 coverage==4.5.3 # https://github.com/nedbat/coveragepy black==19.3b0 # https://github.com/ambv/black -pylint-django==2.0.7 # https://github.com/PyCQA/pylint-django +pylint-django==2.0.8 # https://github.com/PyCQA/pylint-django {%- if cookiecutter.use_celery == 'y' %} pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery {%- endif %} From 7358fef56af367dac58bd9691128ddc416542b93 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Wed, 24 Apr 2019 12:00:28 +0100 Subject: [PATCH 114/126] Update sentry-sdk from 0.7.10 to 0.7.11 --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index d9fa2550..c430e436 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 Collectfast==0.6.2 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==0.7.10 # https://github.com/getsentry/sentry-python +sentry-sdk==0.7.11 # https://github.com/getsentry/sentry-python {%- endif %} # Django From 2f77d48496c98a52eadec4fec82c52f13b035243 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Fri, 26 Apr 2019 12:00:28 +0100 Subject: [PATCH 115/126] Update sentry-sdk from 0.7.11 to 0.7.12 --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index c430e436..21e4cc8d 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 Collectfast==0.6.2 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==0.7.11 # https://github.com/getsentry/sentry-python +sentry-sdk==0.7.12 # https://github.com/getsentry/sentry-python {%- endif %} # Django From 09735eadfd3e36a67800a0e80bbd0d206032972a Mon Sep 17 00:00:00 2001 From: browniebroke Date: Fri, 26 Apr 2019 12:00:32 +0100 Subject: [PATCH 116/126] Update pylint-django from 2.0.8 to 2.0.9 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 5d85b6ff..85f60a4a 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -20,7 +20,7 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar flake8==3.7.5 # https://github.com/PyCQA/flake8 coverage==4.5.3 # https://github.com/nedbat/coveragepy black==19.3b0 # https://github.com/ambv/black -pylint-django==2.0.8 # https://github.com/PyCQA/pylint-django +pylint-django==2.0.9 # https://github.com/PyCQA/pylint-django {%- if cookiecutter.use_celery == 'y' %} pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery {%- endif %} From bf6f17b1b9924672022d0c99475e5dbb834e7d1f Mon Sep 17 00:00:00 2001 From: browniebroke Date: Tue, 30 Apr 2019 12:00:31 +0100 Subject: [PATCH 117/126] Update sentry-sdk from 0.7.12 to 0.7.14 --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 21e4cc8d..4ae99be3 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 Collectfast==0.6.2 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==0.7.12 # https://github.com/getsentry/sentry-python +sentry-sdk==0.7.14 # https://github.com/getsentry/sentry-python {%- endif %} # Django From 07a685326c973e8559c5e0d88ae6863079e618c3 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Tue, 30 Apr 2019 12:00:34 +0100 Subject: [PATCH 118/126] Update djangorestframework from 3.9.2 to 3.9.3 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 39bec2d4..a6031c88 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -29,5 +29,5 @@ django-compressor==2.2 # https://github.com/django-compressor/django-compressor django-redis==4.10.0 # https://github.com/niwinz/django-redis # Django REST Framework -djangorestframework==3.9.2 # https://github.com/encode/django-rest-framework +djangorestframework==3.9.3 # https://github.com/encode/django-rest-framework coreapi==2.3.3 # https://github.com/core-api/python-client From 964662742a63035da4a31839b991cf62a0a5f1d3 Mon Sep 17 00:00:00 2001 From: Craig Margieson Date: Mon, 6 May 2019 15:10:18 +0930 Subject: [PATCH 119/126] Add to contributors. --- CONTRIBUTORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index ded1606b..41bf6f65 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -84,6 +84,7 @@ Listed in alphabetical order. Christopher Clarke `@chrisdev`_ Cole Mackenzie `@cmackenzie1`_ Collederas `@Collederas`_ + Craig Margieson `@cmargieson`_ Cristian Vargas `@cdvv7788`_ Cullen Rhodes `@c-rhodes`_ Dan Shultz `@shultz`_ From 5ab5285e5f741e1c7d87bf0a176ebb8de131aba6 Mon Sep 17 00:00:00 2001 From: Craig Margieson Date: Mon, 6 May 2019 15:13:01 +0930 Subject: [PATCH 120/126] Edit STATIC and MEDIA urls for GCE production. --- {{cookiecutter.project_slug}}/config/settings/production.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 4adbdb9c..63225bee 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -104,7 +104,7 @@ STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage" STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/" {%- elif cookiecutter.cloud_provider == 'GCE' %} -STATIC_URL = "https://storage.googleapis.com/{}/static".format(GS_BUCKET_NAME) +STATIC_URL = "https://storage.googleapis.com/{}/static/".format(GS_BUCKET_NAME) {%- endif %} # MEDIA @@ -128,8 +128,8 @@ class MediaRootS3Boto3Storage(S3Boto3Storage): DEFAULT_FILE_STORAGE = "config.settings.production.MediaRootS3Boto3Storage" MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/" {%- elif cookiecutter.cloud_provider == 'GCE' %} -MEDIA_URL = "https://storage.googleapis.com/{}/media".format(GS_BUCKET_NAME) -MEDIA_ROOT = "https://storage.googleapis.com/{}/media".format(GS_BUCKET_NAME) +MEDIA_URL = "https://storage.googleapis.com/{}/media/".format(GS_BUCKET_NAME) +MEDIA_ROOT = "https://storage.googleapis.com/{}/media/".format(GS_BUCKET_NAME) {%- endif %} # TEMPLATES From 1646daa277372fb0dc5a215e7f12edfb362d248c Mon Sep 17 00:00:00 2001 From: Craig Margieson Date: Mon, 6 May 2019 15:30:02 +0930 Subject: [PATCH 121/126] Added link in contributors. --- CONTRIBUTORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 41bf6f65..6fa9e1c0 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -318,6 +318,7 @@ Listed in alphabetical order. .. _@ericgroom: https://github.com/ericgroom .. _@hanaquadara: https://github.com/hanaquadara .. _@vladdoster: https://github.com/vladdoster +.. _@cmargieson: https://github.com/cmargieson Special Thanks ~~~~~~~~~~~~~~ From 07f2a25219db1d1a69017a1e5cae3193e1771904 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Tue, 7 May 2019 06:52:01 +0100 Subject: [PATCH 122/126] Update psycopg2-binary from 2.8 to 2.8.2 (#2034) --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 85f60a4a..7095af3d 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -6,7 +6,7 @@ Sphinx==2.0.1 # https://github.com/sphinx-doc/sphinx {%- if cookiecutter.use_docker == 'y' %} psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 {%- else %} -psycopg2-binary==2.8 # https://github.com/psycopg/psycopg2 +psycopg2-binary==2.8.2 # https://github.com/psycopg/psycopg2 {%- endif %} # Testing From 642521dc5e80de72bc3a8d7e2bd7127e933ced2e Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 9 May 2019 12:00:32 +0100 Subject: [PATCH 123/126] Update pytest from 4.4.1 to 4.4.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ea10eaa5..3644de16 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ flake8==3.7.6 # Testing # ------------------------------------------------------------------------------ tox==3.9.0 -pytest==4.4.1 +pytest==4.4.2 pytest_cases==1.6.2 pytest-cookies==0.3.0 pyyaml==5.1 From 42fc45d38afb9f81e4f5ae40b9f5782f2ce5f2c8 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Thu, 9 May 2019 12:00:33 +0100 Subject: [PATCH 124/126] Update pytest from 4.4.1 to 4.4.2 --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 7095af3d..3ef434e9 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -12,7 +12,7 @@ psycopg2-binary==2.8.2 # https://github.com/psycopg/psycopg2 # Testing # ------------------------------------------------------------------------------ mypy==0.701 # https://github.com/python/mypy -pytest==4.4.1 # https://github.com/pytest-dev/pytest +pytest==4.4.2 # https://github.com/pytest-dev/pytest pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar # Code quality From 8933aa17c08462d4ef0994f963b6ba2a04071b17 Mon Sep 17 00:00:00 2001 From: shireenrao Date: Fri, 10 May 2019 11:42:07 -0400 Subject: [PATCH 125/126] The signal should be imported from project_slug I am getting an error if I create a signal.py file under users model. Here is the stacktrace Tracking file by folder pattern: migrations Unhandled exception in thread started by .wrapper at 0x000002663A074048> Traceback (most recent call last): File "C:\Apps\Anaconda3\envs\registration\lib\site-packages\django\utils\autoreload.py", line 225, in wrapper fn(*args, **kwargs) File "C:\Apps\Anaconda3\envs\registration\lib\site-packages\django\core\management\commands\runserver.py", line 109, in inner_run autoreload.raise_last_exception() File "C:\Apps\Anaconda3\envs\registration\lib\site-packages\django\utils\autoreload.py", line 248, in raise_last_exception raise _exception[1] File "C:\Apps\Anaconda3\envs\registration\lib\site-packages\django\core\management\__init__.py", line 337, in execute autoreload.check_errors(django.setup)() File "C:\Apps\Anaconda3\envs\registration\lib\site-packages\django\utils\autoreload.py", line 225, in wrapper fn(*args, **kwargs) File "C:\Apps\Anaconda3\envs\registration\lib\site-packages\django\__init__.py", line 24, in setup apps.populate(settings.INSTALLED_APPS) File "C:\Apps\Anaconda3\envs\registration\lib\site-packages\django\apps\registry.py", line 120, in populate app_config.ready() File "C:\Users\srao\projects\kbs\kbs\users\apps.py", line 11, in ready import users.signals # noqa F401 File "C:\Users\srao\projects\kbs\kbs\users\signals.py", line 3, in from .models import User File "C:\Users\srao\projects\kbs\kbs\users\models.py", line 8, in class User(AbstractUser): File "C:\Apps\Anaconda3\envs\registration\lib\site-packages\django\db\models\base.py", line 95, in __new__ "INSTALLED_APPS." % (module, name) RuntimeError: Model class users.models.User doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS. Having the signal be imported from project_slug.users.signal fixes the issue. --- .../{{cookiecutter.project_slug}}/users/apps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/apps.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/apps.py index 854665fd..ded2072f 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/apps.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/apps.py @@ -8,6 +8,6 @@ class UsersAppConfig(AppConfig): def ready(self): try: - import users.signals # noqa F401 + import {{ cookiecutter.project_slug }}.users.signals # noqa F401 except ImportError: pass From 4bca52c835050485a4036d2a451bcc27bddef3ee Mon Sep 17 00:00:00 2001 From: browniebroke Date: Sat, 11 May 2019 12:00:28 +0100 Subject: [PATCH 126/126] Update djangorestframework from 3.9.3 to 3.9.4 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index dc54eb33..29e7f2b9 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -29,5 +29,5 @@ django-compressor==2.2 # https://github.com/django-compressor/django-compressor django-redis==4.10.0 # https://github.com/niwinz/django-redis # Django REST Framework -djangorestframework==3.9.3 # https://github.com/encode/django-rest-framework +djangorestframework==3.9.4 # https://github.com/encode/django-rest-framework coreapi==2.3.3 # https://github.com/core-api/python-client