From 3d25befb3f43d8965816376a4e64b868e0db6f6d Mon Sep 17 00:00:00 2001 From: Delio Castillo Date: Thu, 22 Sep 2016 11:42:16 -0700 Subject: [PATCH 01/31] Updates to anymail 0.5 and adds new config setting for MAILGUN_SENDER_DOMAIN --- CHANGELOG.md | 4 ++++ docs/deployment-on-heroku.rst | 3 ++- docs/deployment-on-pythonanywhere.rst | 3 ++- docs/settings.rst | 1 + {{cookiecutter.project_slug}}/app.json | 3 ++- {{cookiecutter.project_slug}}/config/settings/production.py | 1 + {{cookiecutter.project_slug}}/env.example | 3 ++- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 8 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e614c84a..30851f24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All enhancements and patches to Cookiecutter Django will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +##[2016-09-22] +### Added +- New setting MAILGUN_SENDER_DOMAIN to allow sending mail from any domain other than those registered with mailgun (@jangeador) + ##[2016-09-10] ### Changed - Use app registry instead of INSTALLED_APPS to discover celery tasks (@dhepper) diff --git a/docs/deployment-on-heroku.rst b/docs/deployment-on-heroku.rst index 5b9b4a2c..843e230f 100644 --- a/docs/deployment-on-heroku.rst +++ b/docs/deployment-on-heroku.rst @@ -27,9 +27,10 @@ You can either push the 'deploy' button in your generated README.rst or run thes heroku config:set DJANGO_MAILGUN_SERVER_NAME=YOUR_MALGUN_SERVER heroku config:set DJANGO_MAILGUN_API_KEY=YOUR_MAILGUN_API_KEY + heroku config:set MAILGUN_SENDER_DOMAIN=YOUR_MAILGUN_SENDER_DOMAIN heroku config:set PYTHONHASHSEED=random - heroku config:set DJANGO_ADMIN_URL=\^somelocation/ + heroku config:set DJANGO_ADMIN_URL=\^somelocation/ git push heroku master heroku run python manage.py migrate diff --git a/docs/deployment-on-pythonanywhere.rst b/docs/deployment-on-pythonanywhere.rst index 6aacba15..82399eb1 100644 --- a/docs/deployment-on-pythonanywhere.rst +++ b/docs/deployment-on-pythonanywhere.rst @@ -69,6 +69,7 @@ Add these exports export DJANGO_ADMIN_URL='' export DJANGO_MAILGUN_API_KEY='' export DJANGO_MAILGUN_SERVER_NAME='' + export MAILGUN_SENDER_DOMAIN='' export DJANGO_AWS_ACCESS_KEY_ID= export DJANGO_AWS_SECRET_ACCESS_KEY= export DJANGO_AWS_STORAGE_BUCKET_NAME= @@ -84,7 +85,7 @@ Go to the PythonAnywhere **Databases tab** and configure your database. * For Postgres, setup your superuser password, then open a Postgres console and run a `CREATE DATABASE my-db-name`. You should probably also set up a specific role and permissions for your app, rather than using the superuser credentials. Make a note of the address and port of your postgres server. -* For MySQL, set the password and create a database. More info here: https://help.pythonanywhere.com/pages/UsingMySQL +* For MySQL, set the password and create a database. More info here: https://help.pythonanywhere.com/pages/UsingMySQL * You can also use sqlite if you like! Not recommended for anything beyond toy projects though. diff --git a/docs/settings.rst b/docs/settings.rst index 768ff618..eb6e92a4 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -40,6 +40,7 @@ DJANGO_SENTRY_CLIENT SENTRY_CLIENT n/a DJANGO_SENTRY_LOG_LEVEL SENTRY_LOG_LEVEL n/a logging.INFO DJANGO_MAILGUN_API_KEY MAILGUN_ACCESS_KEY n/a raises error DJANGO_MAILGUN_SERVER_NAME MAILGUN_SERVER_NAME n/a raises error +MAILGUN_SENDER_DOMAIN MAILGUN_SENDER_DOMAIN n/a raises error NEW_RELIC_APP_NAME NEW_RELIC_APP_NAME n/a raises error NEW_RELIC_LICENSE_KEY NEW_RELIC_LICENSE_KEY n/a raises error DJANGO_OPBEAT_APP_ID OPBEAT['APP_ID'] n/a raises error diff --git a/{{cookiecutter.project_slug}}/app.json b/{{cookiecutter.project_slug}}/app.json index 96ab574f..10d2c926 100644 --- a/{{cookiecutter.project_slug}}/app.json +++ b/{{cookiecutter.project_slug}}/app.json @@ -20,7 +20,8 @@ "DJANGO_AWS_SECRET_ACCESS_KEY": "", "DJANGO_AWS_STORAGE_BUCKET_NAME": "", "DJANGO_MAILGUN_SERVER_NAME": "", - "DJANGO_MAILGUN_API_KEY": ""{% if cookiecutter.use_sentry_for_error_reporting == "y" -%}, + "DJANGO_MAILGUN_API_KEY": "" + "MAILGUN_SENDER_DOMAIN": ""{% if cookiecutter.use_sentry_for_error_reporting == "y" -%}, "DJANGO_SENTRY_DSN": ""{%- endif %} }, "scripts": { diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 04a9426f..c46132a3 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -163,6 +163,7 @@ SERVER_EMAIL = env('DJANGO_SERVER_EMAIL', default=DEFAULT_FROM_EMAIL) INSTALLED_APPS += ("anymail", ) ANYMAIL = { "MAILGUN_API_KEY": env('DJANGO_MAILGUN_API_KEY'), + "MAILGUN_SENDER_DOMAIN": env('MAILGUN_SENDER_DOMAIN') } EMAIL_BACKEND = "anymail.backends.mailgun.MailgunBackend" diff --git a/{{cookiecutter.project_slug}}/env.example b/{{cookiecutter.project_slug}}/env.example index 95a6a1d9..b634a49d 100644 --- a/{{cookiecutter.project_slug}}/env.example +++ b/{{cookiecutter.project_slug}}/env.example @@ -16,6 +16,7 @@ DJANGO_AWS_STORAGE_BUCKET_NAME= # Used with email DJANGO_MAILGUN_API_KEY= DJANGO_SERVER_EMAIL= +MAILGUN_SENDER_DOMAIN= # Security! Better to use DNS for this task, but you can use redirect DJANGO_SECURE_SSL_REDIRECT=False @@ -33,4 +34,4 @@ DJANGO_OPBEAT_SECRET_TOKEN {% endif %} {% if cookiecutter.use_compressor == 'y' -%} COMPRESS_ENABLED= -{% endif %} \ No newline at end of file +{% endif %} diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 247bbb33..88300ff7 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -24,7 +24,7 @@ Collectfast==0.2.3 # Email backends for Mailgun, Postmark, SendGrid and more # ------------------------------------------------------- -django-anymail==0.4.2 +django-anymail==0.5 {% if cookiecutter.use_sentry_for_error_reporting == "y" -%} # Raven is the Sentry client From cac685d909c8e90f4489fa520a259ec07f9ace11 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Thu, 22 Sep 2016 18:21:00 -0700 Subject: [PATCH 02/31] Add Experimental AWS Elastic Beanstalk support (#817) Includes: * First pass at Elastic Beanstalk integration * Gets code and elasticache working * Very rudimentary documentation * Includes post hook cleanup --- README.rst | 2 + cookiecutter.json | 3 +- docs/deployment-with-elastic-beanstalk.rst | 54 +++++++++++++++++++ docs/index.rst | 1 + hooks/post_gen_project.py | 26 +++++++-- .../.ebextensions/10_packages.config | 5 ++ .../.ebextensions/20_elasticcache.config | 46 ++++++++++++++++ .../.ebextensions/30_options.config | 6 +++ .../.ebextensions/40_python.config | 17 ++++++ {{cookiecutter.project_slug}}/README.rst | 10 ++++ .../config/settings/production.py | 25 ++++++++- {{cookiecutter.project_slug}}/ebsetenv.py | 31 +++++++++++ {{cookiecutter.project_slug}}/env.example | 1 + 13 files changed, 222 insertions(+), 5 deletions(-) create mode 100644 docs/deployment-with-elastic-beanstalk.rst create mode 100644 {{cookiecutter.project_slug}}/.ebextensions/10_packages.config create mode 100644 {{cookiecutter.project_slug}}/.ebextensions/20_elasticcache.config create mode 100644 {{cookiecutter.project_slug}}/.ebextensions/30_options.config create mode 100644 {{cookiecutter.project_slug}}/.ebextensions/40_python.config create mode 100644 {{cookiecutter.project_slug}}/ebsetenv.py diff --git a/README.rst b/README.rst index a0aa5077..b129a215 100644 --- a/README.rst +++ b/README.rst @@ -42,6 +42,7 @@ Features * Works with Python 2.7.x or 3.5.x * Run tests with unittest or py.test * Customizable PostgreSQL version +* Experimental support for Amazon Elastic Beanstalk Optional Integrations @@ -146,6 +147,7 @@ Answer the prompts with your own desired options_. For example:: 4 - Apache Software License 2.0 5 - Not open source Choose from 1, 2, 3, 4, 5 [1]: 1 + use_elasticbeanstalk_experimental: n Enter the project and take a look around:: diff --git a/cookiecutter.json b/cookiecutter.json index 9b9c6707..ababd56b 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -21,5 +21,6 @@ "postgresql_version": ["9.5", "9.4", "9.3", "9.2"], "js_task_runner": ["Gulp", "Grunt", "None"], "use_lets_encrypt": "n", - "open_source_license": ["MIT", "BSD", "GPLv3", "Apache Software License 2.0", "Not open source"] + "open_source_license": ["MIT", "BSD", "GPLv3", "Apache Software License 2.0", "Not open source"], + "use_elasticbeanstalk_experimental": "n" } diff --git a/docs/deployment-with-elastic-beanstalk.rst b/docs/deployment-with-elastic-beanstalk.rst new file mode 100644 index 00000000..e88decfc --- /dev/null +++ b/docs/deployment-with-elastic-beanstalk.rst @@ -0,0 +1,54 @@ +Deployment with Elastic Beanstalk +========================================== + +.. index:: Elastic Beanstalk + +Warning: Experimental +--------------------- + +This is experimental. For the time being there will be bugs and issues. If you've never used Elastic Beanstalk before, please hold off before trying this option. + +On the other hand, we need help cleaning this up. If you do have knowledge of Elastic Beanstalk, we would appreciate the help. :) + +Prerequisites +------------- + +* awsebcli + +Instructions +------------- + +``` +# creates the directory of environments (servers) +eb init -p python3.4 {{ cookiecutter.project_slug }} + +# Creates the environment (server) where the app will run +eb create {{ cookiecutter.project_slug }} +# Note: This will fail on a postgres error, because postgres doesn't exist yet + +# Make sure you are in the right environment +eb list + +# If you are not in the right environment +eb use {{ cookiecutter.project_slug }} + +# Set the environment variables +python ebsetenv.py + +# Go to EB AWS config. Create new RDS database (postgres, 9.4.9, db.t2.micro) +# Get some coffee, this is going to take a while + +# Deploy again +eb deploy + +# Take a look +eb open +``` + +FAQ +----- + +Why Not Use Docker on Elastic Beanstalk? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Because I didn't want to add an abstraction (Docker) on top of an abstraction (Elastic Beanstalk). diff --git a/docs/index.rst b/docs/index.rst index 07cedc4a..bfa88f18 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -25,6 +25,7 @@ Contents: faq troubleshooting my-favorite-cookie + deployment-with-elastic-beanstalk Indices and tables ================== diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index dd6a3f07..0736c375 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -115,7 +115,10 @@ def remove_heroku_files(): """ Removes files needed for heroku if it isn't going to be used """ - for filename in ["app.json", "Procfile", "requirements.txt", "runtime.txt"]: + filenames = ["app.json", "Procfile", "runtime.txt"] + if '{{ cookiecutter.use_elasticbeanstalk_experimental }}'.lower() != 'y': + filenames.append("requirements.txt") + for filename in ["app.json", "Procfile", "runtime.txt"]: file_name = os.path.join(PROJECT_DIRECTORY, filename) remove_file(file_name) @@ -179,6 +182,22 @@ def remove_copying_files(): PROJECT_DIRECTORY, filename )) +def remove_elasticbeanstalk(): + """ + Removes elastic beanstalk components + """ + docs_dir_location = os.path.join(PROJECT_DIRECTORY, '.ebextensions') + if os.path.exists(docs_dir_location): + shutil.rmtree(docs_dir_location) + + filenames = ["ebsetenv.py", ] + if '{{ cookiecutter.use_heroku }}'.lower() != 'y': + filenames.append("requirements.txt") + for filename in filenames: + os.remove(os.path.join( + PROJECT_DIRECTORY, filename + )) + # IN PROGRESS # def copy_doc_files(project_directory): # cookiecutters_dir = DEFAULT_CONFIG['cookiecutters_dir'] @@ -258,5 +277,6 @@ if '{{ cookiecutter.use_lets_encrypt }}'.lower() == 'y' and '{{ cookiecutter.use if '{{ cookiecutter.open_source_license}}' != 'GPLv3': remove_copying_files() -# 4. Copy files from /docs/ to {{ cookiecutter.project_slug }}/docs/ -# copy_doc_files(PROJECT_DIRECTORY) +# 12. Remove Elastic Beanstalk files +if '{{ cookiecutter.use_elasticbeanstalk_experimental }}'.lower() != 'y': + remove_elasticbeanstalk() diff --git a/{{cookiecutter.project_slug}}/.ebextensions/10_packages.config b/{{cookiecutter.project_slug}}/.ebextensions/10_packages.config new file mode 100644 index 00000000..c0774efa --- /dev/null +++ b/{{cookiecutter.project_slug}}/.ebextensions/10_packages.config @@ -0,0 +1,5 @@ +packages: + yum: + git: [] + postgresql94-devel: [] + libjpeg-turbo-devel: [] diff --git a/{{cookiecutter.project_slug}}/.ebextensions/20_elasticcache.config b/{{cookiecutter.project_slug}}/.ebextensions/20_elasticcache.config new file mode 100644 index 00000000..539f5509 --- /dev/null +++ b/{{cookiecutter.project_slug}}/.ebextensions/20_elasticcache.config @@ -0,0 +1,46 @@ +#This sample requires you to create a separate configuration file that defines the custom +# option settings for CacheCluster properties. + +Resources: + MyCacheSecurityGroup: + Type: "AWS::EC2::SecurityGroup" + Properties: + GroupDescription: "Lock cache down to webserver access only" + SecurityGroupIngress : + - IpProtocol : "tcp" + FromPort : + Fn::GetOptionSetting: + OptionName : "CachePort" + DefaultValue: "6379" + ToPort : + Fn::GetOptionSetting: + OptionName : "CachePort" + DefaultValue: "6379" + SourceSecurityGroupName: + Ref: "AWSEBSecurityGroup" + MyElastiCache: + Type: "AWS::ElastiCache::CacheCluster" + Properties: + CacheNodeType: + Fn::GetOptionSetting: + OptionName : "CacheNodeType" + DefaultValue : "cache.t1.micro" + NumCacheNodes: + Fn::GetOptionSetting: + OptionName : "NumCacheNodes" + DefaultValue : "1" + Engine: + Fn::GetOptionSetting: + OptionName : "Engine" + DefaultValue : "redis" + VpcSecurityGroupIds: + - + Fn::GetAtt: + - MyCacheSecurityGroup + - GroupId + +Outputs: + ElastiCache: + Description : "ID of ElastiCache Cache Cluster with Redis Engine" + Value : + Ref : "MyElastiCache" diff --git a/{{cookiecutter.project_slug}}/.ebextensions/30_options.config b/{{cookiecutter.project_slug}}/.ebextensions/30_options.config new file mode 100644 index 00000000..d7135c3f --- /dev/null +++ b/{{cookiecutter.project_slug}}/.ebextensions/30_options.config @@ -0,0 +1,6 @@ +option_settings: + "aws:elasticbeanstalk:customoption": + CacheNodeType : cache.t1.micro + NumCacheNodes : 1 + Engine : redis + CachePort : 6379 diff --git a/{{cookiecutter.project_slug}}/.ebextensions/40_python.config b/{{cookiecutter.project_slug}}/.ebextensions/40_python.config new file mode 100644 index 00000000..02636e1a --- /dev/null +++ b/{{cookiecutter.project_slug}}/.ebextensions/40_python.config @@ -0,0 +1,17 @@ +container_commands: + 01_migrate: + command: "source /opt/python/run/venv/bin/activate && python manage.py migrate" + leader_only: True + 02_collectstatic: + command: "source /opt/python/run/venv/bin/activate && python manage.py collectstatic --noinput" +option_settings: + "aws:elasticbeanstalk:application:environment": + DJANGO_SETTINGS_MODULE: "config.settings.production" + REDIS_ENDPOINT_ADDRESS: '`{ "Fn::GetAtt" : [ "MyElastiCache", "RedisEndpoint.Address"]}`' + REDIS_PORT: '`{ "Fn::GetAtt" : [ "MyElastiCache", "RedisEndpoint.Port"]}`' + "aws:elasticbeanstalk:container:python": + WSGIPath: "config/wsgi.py" + NumProcesses: 3 + NumThreads: 20 + "aws:elasticbeanstalk:container:python:staticfiles": + "/static/": "www/static/" diff --git a/{{cookiecutter.project_slug}}/README.rst b/{{cookiecutter.project_slug}}/README.rst index f760a1e2..b248a2c3 100644 --- a/{{cookiecutter.project_slug}}/README.rst +++ b/{{cookiecutter.project_slug}}/README.rst @@ -138,3 +138,13 @@ See detailed `cookiecutter-django Docker documentation`_. .. _`cookiecutter-django Docker documentation`: http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html {% endif %} +{% if cookiecutter.use_elasticbeanstalk_experimental %} + +Elastic Beanstalk +~~~~~~~~~~~~~~~~~~ + +See detailed `cookiecutter-django Elastic Beanstalk documentation`_. + +.. _`cookiecutter-django Docker documentation`: http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-elastic-beanstalk.html + +{% endif %} diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index c46132a3..7934182a 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -178,16 +178,39 @@ TEMPLATES[0]['OPTIONS']['loaders'] = [ # DATABASE CONFIGURATION # ------------------------------------------------------------------------------ +{% if cookiecutter.use_elasticbeanstalk_experimental -%} +# Uses Amazon RDS for database hosting, which doesn't follow the Heroku-style spec +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': env('RDS_DB_NAME'), + 'USER': env('RDS_USERNAME'), + 'PASSWORD': env('RDS_PASSWORD'), + 'HOST': env('RDS_HOSTNAME'), + 'PORT': env('RDS_PORT'), + } +} +{% else %} +# Use the Heroku-style specification # Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ DATABASES['default'] = env.db('DATABASE_URL') +{%- endif %} # CACHING # ------------------------------------------------------------------------------ +{% if cookiecutter.use_elasticbeanstalk_experimental -%} +REDIS_LOCATION = "redis://{}:{}/0".format( + env('REDIS_ENDPOINT_ADDRESS'), + env('REDIS_PORT') +) +{% else %} +REDIS_LOCATION = '{0}/{1}'.format(env('REDIS_URL', default='redis://127.0.0.1:6379'), 0) +{%- endif %} # Heroku URL does not pass the DB number, so we parse it in CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', - 'LOCATION': '{0}/{1}'.format(env('REDIS_URL', default='redis://127.0.0.1:6379'), 0), + 'LOCATION': REDIS_LOCATION, 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', 'IGNORE_EXCEPTIONS': True, # mimics memcache behavior. diff --git a/{{cookiecutter.project_slug}}/ebsetenv.py b/{{cookiecutter.project_slug}}/ebsetenv.py new file mode 100644 index 00000000..fbb8dc2d --- /dev/null +++ b/{{cookiecutter.project_slug}}/ebsetenv.py @@ -0,0 +1,31 @@ +"""Converts a .env file to Elastic Beanstalk environment variables""" + +from sys import exit +from subprocess import check_call + +try: + import dotenv +except ImportError: + print("Please install the 'dotenv' library: 'pip install dotenv'") + exit() + +def main(): + command = ['eb', 'setenv'] + failures = [] + for key, value in dotenv.Dotenv('.env').items(): + if key.startswith('POSTGRES'): + continue + if value: + command.append("{}={}".format(key, value)) + else: + failures.append(key) + if failures: + for failure in failures: + print("{} requires a value".format(failure)) + else: + print(' '.join(command)) + check_call(command) + + +if __name__ == '__main__': + main() diff --git a/{{cookiecutter.project_slug}}/env.example b/{{cookiecutter.project_slug}}/env.example index b634a49d..66a3570d 100644 --- a/{{cookiecutter.project_slug}}/env.example +++ b/{{cookiecutter.project_slug}}/env.example @@ -1,3 +1,4 @@ + # PostgreSQL POSTGRES_PASSWORD=mysecretpass POSTGRES_USER=postgresuser From 0eaf6a7b0ca2d7fd0bb7c04b0c00c99db9f790c0 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Thu, 22 Sep 2016 18:32:56 -0700 Subject: [PATCH 03/31] Fix FAQ --- docs/deployment-with-elastic-beanstalk.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment-with-elastic-beanstalk.rst b/docs/deployment-with-elastic-beanstalk.rst index e88decfc..fb57607f 100644 --- a/docs/deployment-with-elastic-beanstalk.rst +++ b/docs/deployment-with-elastic-beanstalk.rst @@ -51,4 +51,4 @@ FAQ Why Not Use Docker on Elastic Beanstalk? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Because I didn't want to add an abstraction (Docker) on top of an abstraction (Elastic Beanstalk). +Because I didn't want to add an abstraction (Docker) on top of an abstraction (Elastic Beanstalk) on top of an abstraction (Cookiecutter Django). From 716717fe53162893ba8941030c03f3d7d7f3bb58 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Thu, 22 Sep 2016 21:45:16 -0700 Subject: [PATCH 04/31] Fix markup --- docs/deployment-with-elastic-beanstalk.rst | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/deployment-with-elastic-beanstalk.rst b/docs/deployment-with-elastic-beanstalk.rst index fb57607f..ae3f41a5 100644 --- a/docs/deployment-with-elastic-beanstalk.rst +++ b/docs/deployment-with-elastic-beanstalk.rst @@ -18,32 +18,32 @@ Prerequisites Instructions ------------- -``` -# creates the directory of environments (servers) -eb init -p python3.4 {{ cookiecutter.project_slug }} +:: -# Creates the environment (server) where the app will run -eb create {{ cookiecutter.project_slug }} -# Note: This will fail on a postgres error, because postgres doesn't exist yet + # creates the directory of environments (servers) + eb init -p python3.4 {{ cookiecutter.project_slug }} -# Make sure you are in the right environment -eb list + # Creates the environment (server) where the app will run + eb create {{ cookiecutter.project_slug }} + # Note: This will fail on a postgres error, because postgres doesn't exist yet -# If you are not in the right environment -eb use {{ cookiecutter.project_slug }} + # Make sure you are in the right environment + eb list -# Set the environment variables -python ebsetenv.py + # If you are not in the right environment + eb use {{ cookiecutter.project_slug }} -# Go to EB AWS config. Create new RDS database (postgres, 9.4.9, db.t2.micro) -# Get some coffee, this is going to take a while + # Set the environment variables + python ebsetenv.py -# Deploy again -eb deploy + # Go to EB AWS config. Create new RDS database (postgres, 9.4.9, db.t2.micro) + # Get some coffee, this is going to take a while -# Take a look -eb open -``` + # Deploy again + eb deploy + + # Take a look + eb open FAQ ----- @@ -51,4 +51,4 @@ FAQ Why Not Use Docker on Elastic Beanstalk? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Because I didn't want to add an abstraction (Docker) on top of an abstraction (Elastic Beanstalk) on top of an abstraction (Cookiecutter Django). +Because I didn't want to add an abstraction (Docker) on top of an abstraction (Elastic Beanstalk) on top of an abstraction (Cookiecutter Django). From 4b95bd9c5e53373e32019b71909629fb0e141d18 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Fri, 23 Sep 2016 17:14:17 -0700 Subject: [PATCH 05/31] A little cleanup of the EB docs --- docs/deployment-with-elastic-beanstalk.rst | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/deployment-with-elastic-beanstalk.rst b/docs/deployment-with-elastic-beanstalk.rst index ae3f41a5..5074770f 100644 --- a/docs/deployment-with-elastic-beanstalk.rst +++ b/docs/deployment-with-elastic-beanstalk.rst @@ -18,18 +18,28 @@ Prerequisites Instructions ------------- +If you haven't done so, create a directory of environments. + :: - # creates the directory of environments (servers) eb init -p python3.4 {{ cookiecutter.project_slug }} - # Creates the environment (server) where the app will run - eb create {{ cookiecutter.project_slug }} - # Note: This will fail on a postgres error, because postgres doesn't exist yet - # Make sure you are in the right environment +Once that is done, create the environment (server) where the app will run + +:: + + eb create {{ cookiecutter.project_slug }} + # Note: This will eventually fail on a postgres error, because postgres doesn't exist yet + +Now make sure you are in the right environment + +:: + eb list +TODO: Finsh it:: + # If you are not in the right environment eb use {{ cookiecutter.project_slug }} From c4ad073f0d15eef870109eb36a1d9199968513d1 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Mon, 26 Sep 2016 09:19:15 -0700 Subject: [PATCH 06/31] Made Elastic Beanstalk support incompatible with Docker and Heroku --- cookiecutter.json | 4 ++-- hooks/pre_gen_project.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cookiecutter.json b/cookiecutter.json index ababd56b..bf729b67 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -17,10 +17,10 @@ "use_python3": "y", "use_docker": "y", "use_heroku": "n", + "use_elasticbeanstalk_experimental": "n", "use_compressor": "n", "postgresql_version": ["9.5", "9.4", "9.3", "9.2"], "js_task_runner": ["Gulp", "Grunt", "None"], "use_lets_encrypt": "n", - "open_source_license": ["MIT", "BSD", "GPLv3", "Apache Software License 2.0", "Not open source"], - "use_elasticbeanstalk_experimental": "n" + "open_source_license": ["MIT", "BSD", "GPLv3", "Apache Software License 2.0", "Not open source"] } diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index 9cd168bc..cd31774e 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -3,4 +3,9 @@ project_slug = '{{ cookiecutter.project_slug }}' if hasattr(project_slug, 'isidentifier'): assert project_slug.isidentifier(), 'Project slug should be valid Python identifier!' +elasticbeanstalk = '{{ cookiecutter.use_elasticbeanstalk_experimental }}'.lower() +heroku = '{{ cookiecutter.use_heroku }}'.lower() +docker = '{{ cookiecutter.use_docker }}'.lower() +if elasticbeanstalk == 'y' and (heroku == 'y' or docker == 'y'): + raise Exception("Cookiecutter Django's EXPERIMENTAL Elastic Beanstalk support is incompatible with Heroku and Docker setups.") From d31e86fc8ace6e273cc19271139f9ac52d3db085 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Mon, 26 Sep 2016 09:28:35 -0700 Subject: [PATCH 07/31] Now includes message for missing .env file. Fixed #819 --- {{cookiecutter.project_slug}}/ebsetenv.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/{{cookiecutter.project_slug}}/ebsetenv.py b/{{cookiecutter.project_slug}}/ebsetenv.py index fbb8dc2d..ba9652db 100644 --- a/{{cookiecutter.project_slug}}/ebsetenv.py +++ b/{{cookiecutter.project_slug}}/ebsetenv.py @@ -1,5 +1,6 @@ """Converts a .env file to Elastic Beanstalk environment variables""" +import os from sys import exit from subprocess import check_call @@ -10,10 +11,15 @@ except ImportError: exit() def main(): + if not os.path.exists('.env'): + print('ERROR!! .env file is missing!') + print("Please copy 'env.example' to '.env' and add appropriate values") + exit() command = ['eb', 'setenv'] failures = [] for key, value in dotenv.Dotenv('.env').items(): if key.startswith('POSTGRES'): + print('Skipping POSTGRES values - Amazon RDS provides these') continue if value: command.append("{}={}".format(key, value)) From f803f8f2ab29ae621f00a817ece03ed0cdd144f3 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Mon, 26 Sep 2016 10:23:45 -0700 Subject: [PATCH 08/31] FAQ entry on combining multiple deployment options --- docs/deployment-with-elastic-beanstalk.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/deployment-with-elastic-beanstalk.rst b/docs/deployment-with-elastic-beanstalk.rst index 5074770f..54c32fec 100644 --- a/docs/deployment-with-elastic-beanstalk.rst +++ b/docs/deployment-with-elastic-beanstalk.rst @@ -62,3 +62,8 @@ Why Not Use Docker on Elastic Beanstalk? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because I didn't want to add an abstraction (Docker) on top of an abstraction (Elastic Beanstalk) on top of an abstraction (Cookiecutter Django). + +Why Can't I Use Both Docker/Heroku with Elastic Beanstalk? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Because the environment variables that our Docker and Heroku setups use for PostgreSQL access is different then how Amazon RDS handles this access. At this time we're just trying to get things to work reliably with Elastic Beanstalk, and full integration will come later. From a091dcbae890240658a99bf8405b2fa7fe974ad9 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Wed, 28 Sep 2016 16:42:02 -0700 Subject: [PATCH 09/31] Fix elastic beanstalk checks --- {{cookiecutter.project_slug}}/README.rst | 6 +++--- {{cookiecutter.project_slug}}/config/settings/production.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/{{cookiecutter.project_slug}}/README.rst b/{{cookiecutter.project_slug}}/README.rst index b248a2c3..e06a85ba 100644 --- a/{{cookiecutter.project_slug}}/README.rst +++ b/{{cookiecutter.project_slug}}/README.rst @@ -117,7 +117,7 @@ Deployment ---------- The following details how to deploy this application. -{% if cookiecutter.use_heroku == "y" %} +{% if cookiecutter.use_heroku.lower() == "y" %} Heroku ^^^^^^ @@ -129,7 +129,7 @@ See detailed `cookiecutter-django Heroku documentation`_. .. _`cookiecutter-django Heroku documentation`: http://cookiecutter-django.readthedocs.io/en/latest/deployment-on-heroku.html {% endif %} -{% if cookiecutter.use_docker == "y" %} +{% if cookiecutter.use_docker.lower() == "y" %} Docker ^^^^^^ @@ -138,7 +138,7 @@ See detailed `cookiecutter-django Docker documentation`_. .. _`cookiecutter-django Docker documentation`: http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html {% endif %} -{% if cookiecutter.use_elasticbeanstalk_experimental %} +{% if cookiecutter.use_elasticbeanstalk_experimental.lower() == 'y' %} Elastic Beanstalk ~~~~~~~~~~~~~~~~~~ diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 7934182a..2201c3fc 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -178,7 +178,7 @@ TEMPLATES[0]['OPTIONS']['loaders'] = [ # DATABASE CONFIGURATION # ------------------------------------------------------------------------------ -{% if cookiecutter.use_elasticbeanstalk_experimental -%} +{% if cookiecutter.use_elasticbeanstalk_experimental.lower() == 'y' -%} # Uses Amazon RDS for database hosting, which doesn't follow the Heroku-style spec DATABASES = { 'default': { @@ -198,7 +198,7 @@ DATABASES['default'] = env.db('DATABASE_URL') # CACHING # ------------------------------------------------------------------------------ -{% if cookiecutter.use_elasticbeanstalk_experimental -%} +{% if cookiecutter.use_elasticbeanstalk_experimental.lower() == 'y' -%} REDIS_LOCATION = "redis://{}:{}/0".format( env('REDIS_ENDPOINT_ADDRESS'), env('REDIS_PORT') From ab52466f445da849bdc99ef3e446fc1f5d040528 Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Thu, 29 Sep 2016 00:14:11 -0300 Subject: [PATCH 10/31] Bump for 1.9.9-05 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 35685f3b..30df6fdd 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ except ImportError: # Our version ALWAYS matches the version of Django we support # If Django has a new release, we branch, tag, then update this setting after the tag. -version = '1.9.9-04' +version = '1.9.9-05' if sys.argv[-1] == 'tag': os.system('git tag -a %s -m "version %s"' % (version, version)) From f2aab6edc3ddbe3dd003041f39c0a28cce6f01b4 Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Thu, 15 Sep 2016 00:28:33 -0300 Subject: [PATCH 11/31] rename MIDDLEWARE_CLASSES to MIDDLEWARE --- {{cookiecutter.project_slug}}/config/settings/common.py | 2 +- {{cookiecutter.project_slug}}/config/settings/local.py | 2 +- .../config/settings/production.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/{{cookiecutter.project_slug}}/config/settings/common.py b/{{cookiecutter.project_slug}}/config/settings/common.py index c9433416..ef2d53b3 100644 --- a/{{cookiecutter.project_slug}}/config/settings/common.py +++ b/{{cookiecutter.project_slug}}/config/settings/common.py @@ -53,7 +53,7 @@ INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS # MIDDLEWARE CONFIGURATION # ------------------------------------------------------------------------------ -MIDDLEWARE_CLASSES = ( +MIDDLEWARE = ( 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', diff --git a/{{cookiecutter.project_slug}}/config/settings/local.py b/{{cookiecutter.project_slug}}/config/settings/local.py index e6fd99f8..c72d3af1 100644 --- a/{{cookiecutter.project_slug}}/config/settings/local.py +++ b/{{cookiecutter.project_slug}}/config/settings/local.py @@ -50,7 +50,7 @@ CACHES = { # django-debug-toolbar # ------------------------------------------------------------------------------ -MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',) +MIDDLEWARE += ('debug_toolbar.middleware.DebugToolbarMiddleware',) INSTALLED_APPS += ('debug_toolbar', ) INTERNAL_IPS = ['127.0.0.1', '10.0.2.2', ] diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 2201c3fc..7fa726f6 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -42,11 +42,11 @@ INSTALLED_APPS += ('raven.contrib.django.raven_compat', ) # Use Whitenoise to serve static files # See: https://whitenoise.readthedocs.io/ WHITENOISE_MIDDLEWARE = ('whitenoise.middleware.WhiteNoiseMiddleware', ) -MIDDLEWARE_CLASSES = WHITENOISE_MIDDLEWARE + MIDDLEWARE_CLASSES +MIDDLEWARE = WHITENOISE_MIDDLEWARE + MIDDLEWARE {% endif %} {%- if cookiecutter.use_sentry_for_error_reporting == 'y' -%} RAVEN_MIDDLEWARE = ('raven.contrib.django.raven_compat.middleware.SentryResponseErrorIdMiddleware', ) -MIDDLEWARE_CLASSES = RAVEN_MIDDLEWARE + MIDDLEWARE_CLASSES +MIDDLEWARE = RAVEN_MIDDLEWARE + MIDDLEWARE {% endif %} {%- if cookiecutter.use_opbeat == 'y' -%} # opbeat integration @@ -57,9 +57,9 @@ OPBEAT = { 'APP_ID': env('DJANGO_OPBEAT_APP_ID'), 'SECRET_TOKEN': env('DJANGO_OPBEAT_SECRET_TOKEN') } -MIDDLEWARE_CLASSES = ( +MIDDLEWARE = ( 'opbeat.contrib.django.middleware.OpbeatAPMMiddleware', -) + MIDDLEWARE_CLASSES +) + MIDDLEWARE {% endif %} # SECURITY CONFIGURATION From f040921d9a5c1e7c506c9059d67d5a199581ef05 Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Thu, 15 Sep 2016 00:37:57 -0300 Subject: [PATCH 12/31] add default AUTH_PASSWORD_VALIDATORS --- .../config/settings/common.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/{{cookiecutter.project_slug}}/config/settings/common.py b/{{cookiecutter.project_slug}}/config/settings/common.py index ef2d53b3..04998575 100644 --- a/{{cookiecutter.project_slug}}/config/settings/common.py +++ b/{{cookiecutter.project_slug}}/config/settings/common.py @@ -200,6 +200,26 @@ ROOT_URLCONF = 'config.urls' # See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application WSGI_APPLICATION = 'config.wsgi.application' + +# PASSWORD VALIDATION +# 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', + }, +] + # AUTHENTICATION CONFIGURATION # ------------------------------------------------------------------------------ AUTHENTICATION_BACKENDS = ( From 178844d616b5826200ca34357f3daa1a13d74ecc Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Thu, 15 Sep 2016 00:41:48 -0300 Subject: [PATCH 13/31] use manage.py from django 1.10 --- {{cookiecutter.project_slug}}/manage.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/{{cookiecutter.project_slug}}/manage.py b/{{cookiecutter.project_slug}}/manage.py index b41522c7..86d03b31 100755 --- a/{{cookiecutter.project_slug}}/manage.py +++ b/{{cookiecutter.project_slug}}/manage.py @@ -5,6 +5,19 @@ import sys if __name__ == '__main__': os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.local') - from django.core.management import execute_from_command_line - + try: + from django.core.management import execute_from_command_line + except ImportError: + # The above import may fail for some other reason. Ensure that the + # issue is really that Django is missing to avoid masking other + # exceptions on Python 2. + try: + import django + except ImportError: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) + raise execute_from_command_line(sys.argv) From 4f9bb652f243084ae86802b1c915539b01225102 Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Thu, 15 Sep 2016 00:56:48 -0300 Subject: [PATCH 14/31] ignore F401 error on manage.py --- {{cookiecutter.project_slug}}/manage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/manage.py b/{{cookiecutter.project_slug}}/manage.py index 86d03b31..9de71376 100755 --- a/{{cookiecutter.project_slug}}/manage.py +++ b/{{cookiecutter.project_slug}}/manage.py @@ -12,7 +12,7 @@ if __name__ == '__main__': # issue is really that Django is missing to avoid masking other # exceptions on Python 2. try: - import django + import django # noqa except ImportError: raise ImportError( "Couldn't import Django. Are you sure it's installed and " From 6c0cb7ed72d580d8b4a87390b2aa018f32548a2b Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Thu, 15 Sep 2016 00:59:26 -0300 Subject: [PATCH 15/31] update django to 1.10.1 --- setup.py | 4 ++-- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 30df6fdd..a20a28b2 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ except ImportError: # Our version ALWAYS matches the version of Django we support # If Django has a new release, we branch, tag, then update this setting after the tag. -version = '1.9.9-05' +version = '1.10.1' if sys.argv[-1] == 'tag': os.system('git tag -a %s -m "version %s"' % (version, version)) @@ -34,7 +34,7 @@ setup( classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Console', - 'Framework :: Django :: 1.9', + 'Framework :: Django :: 1.10', 'Intended Audience :: Developers', 'Natural Language :: English', 'License :: OSI Approved :: BSD License', diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index fcc10ba2..13378d8f 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -7,7 +7,7 @@ wheel==0.29.0 {%- endif %} # Bleeding edge Django -django==1.9.9 +django==1.10.1 # Configuration django-environ==0.4.0 From 6cbc513e6d50c250819f679f887d7a00a2e79818 Mon Sep 17 00:00:00 2001 From: Steve Steiner Date: Thu, 15 Sep 2016 12:40:15 -0400 Subject: [PATCH 16/31] Make test_docker.sh tests pass by passing new password auth rules --- tests/test_cookiecutter_generation.py | 0 tests/test_docker.sh | 0 .../users/tests/test_admin.py | 10 +++++----- 3 files changed, 5 insertions(+), 5 deletions(-) mode change 100644 => 100755 tests/test_cookiecutter_generation.py mode change 100644 => 100755 tests/test_docker.sh diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py old mode 100644 new mode 100755 diff --git a/tests/test_docker.sh b/tests/test_docker.sh old mode 100644 new mode 100755 diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py index 10b07b74..a1ff0b84 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py @@ -6,14 +6,14 @@ from ..admin import MyUserCreationForm class TestMyUserCreationForm(TestCase): def setUp(self): - self.user = self.make_user() + self.user = self.make_user('notalamode', 'notalamodespassword') def test_clean_username_success(self): # Instantiate the form with a new username form = MyUserCreationForm({ 'username': 'alamode', - 'password1': '123456', - 'password2': '123456', + 'password1': '7jefB#f@Cc7YJB]2v', + 'password2': '7jefB#f@Cc7YJB]2v', }) # Run is_valid() to trigger the validation valid = form.is_valid() @@ -27,8 +27,8 @@ class TestMyUserCreationForm(TestCase): # Instantiate the form with the same username as self.user form = MyUserCreationForm({ 'username': self.user.username, - 'password1': '123456', - 'password2': '123456', + 'password1': 'notalamodespassword', + 'password2': 'notalamodespassword', }) # Run is_valid() to trigger the validation, which is going to fail # because the username is already taken From 2aed9268b6159a0dd1088ca8eac93961955b3bea Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Tue, 20 Sep 2016 19:03:35 -0300 Subject: [PATCH 17/31] update frontend dependencies --- .../templates/base.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html index 3518fe6e..94f9ef9f 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html @@ -14,8 +14,8 @@ {% block css %} - - + + {% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress css %}{% endraw %}{% endif %}{% raw %} @@ -89,10 +89,10 @@ ================================================== --> {% block javascript %} - - - - + + + + From b4e6e081000faad01f1a7e0eb0e1d6020aff2f6d Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Tue, 20 Sep 2016 19:05:36 -0300 Subject: [PATCH 18/31] change 'admin' url, to stay the same as generated by django 1.10 https://github.com/django/django/blob/1.10.1/django/conf/project_template/project_name/urls.py-tpl#L20 --- {{cookiecutter.project_slug}}/config/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/config/urls.py b/{{cookiecutter.project_slug}}/config/urls.py index f3a62112..cbb977ff 100644 --- a/{{cookiecutter.project_slug}}/config/urls.py +++ b/{{cookiecutter.project_slug}}/config/urls.py @@ -13,7 +13,7 @@ urlpatterns = [ url(r'^about/$', TemplateView.as_view(template_name='pages/about.html'), name='about'), # Django Admin, use {% raw %}{% url 'admin:index' %}{% endraw %} - url(settings.ADMIN_URL, include(admin.site.urls)), + url(settings.ADMIN_URL, admin.site.urls), # User management url(r'^users/', include('{{ cookiecutter.project_slug }}.users.urls', namespace='users')), From 0e9eafbfc43be2ff37e8488d226bdfa4a3e8565d Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Fri, 23 Sep 2016 01:28:27 -0300 Subject: [PATCH 19/31] sync migrations with django1.10 --- .../contrib/sites/migrations/0001_initial.py | 23 ++++++----- .../migrations/0002_alter_domain_unique.py | 23 +++++++++++ ...me.py => 0003_set_site_domain_and_name.py} | 2 +- .../users/migrations/0001_initial.py | 39 ++++++++++--------- 4 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_alter_domain_unique.py rename {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/{0002_set_site_domain_and_name.py => 0003_set_site_domain_and_name.py} (96%) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0001_initial.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0001_initial.py index 555d02c4..b1803682 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0001_initial.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0001_initial.py @@ -1,31 +1,34 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations import django.contrib.sites.models +from django.contrib.sites.models import _simple_domain_name_validator +from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( name='Site', fields=[ - ('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)), - ('domain', models.CharField(verbose_name='domain name', max_length=100, validators=[django.contrib.sites.models._simple_domain_name_validator])), - ('name', models.CharField(verbose_name='display name', max_length=50)), + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('domain', models.CharField( + max_length=100, verbose_name='domain name', validators=[_simple_domain_name_validator] + )), + ('name', models.CharField(max_length=50, verbose_name='display name')), ], options={ - 'verbose_name_plural': 'sites', - 'verbose_name': 'site', - 'db_table': 'django_site', 'ordering': ('domain',), + 'db_table': 'django_site', + 'verbose_name': 'site', + 'verbose_name_plural': 'sites', }, + bases=(models.Model,), managers=[ - (b'objects', django.contrib.sites.models.SiteManager()), + ('objects', django.contrib.sites.models.SiteManager()), ], ), ] diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_alter_domain_unique.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_alter_domain_unique.py new file mode 100644 index 00000000..468718cd --- /dev/null +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_alter_domain_unique.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import django.contrib.sites.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sites', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='site', + name='domain', + field=models.CharField( + max_length=100, unique=True, validators=[django.contrib.sites.models._simple_domain_name_validator], + verbose_name='domain name' + ), + ), + ] diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_set_site_domain_and_name.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py similarity index 96% rename from {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_set_site_domain_and_name.py rename to {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py index e6292f0b..348989e1 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_set_site_domain_and_name.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py @@ -38,7 +38,7 @@ def update_site_backward(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('sites', '0001_initial'), + ('sites', '0002_alter_domain_unique'), ] operations = [ diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py index 8327d289..626e10f3 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py @@ -1,44 +1,47 @@ # -*- coding: utf-8 -*- +# Generated by Django 1.9.9 on 2016-09-23 04:10 from __future__ import unicode_literals -from django.db import models, migrations -import django.utils.timezone import django.contrib.auth.models import django.core.validators +from django.db import migrations, models +import django.utils.timezone class Migration(migrations.Migration): + initial = True + dependencies = [ - ('auth', '0006_require_contenttypes_0002'), + ('auth', '0007_alter_validators_add_error_messages'), ] operations = [ migrations.CreateModel( name='User', fields=[ - ('id', models.AutoField(primary_key=True, verbose_name='ID', serialize=False, auto_created=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(null=True, verbose_name='last login', blank=True)), - ('is_superuser', models.BooleanField(help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status', default=False)), - ('username', models.CharField(max_length=30, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.', 'invalid')], verbose_name='username', error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True)), - ('first_name', models.CharField(max_length=30, verbose_name='first name', blank=True)), - ('last_name', models.CharField(max_length=30, verbose_name='last name', blank=True)), - ('email', models.EmailField(max_length=254, verbose_name='email address', blank=True)), - ('is_staff', models.BooleanField(help_text='Designates whether the user can log into this admin site.', verbose_name='staff status', default=False)), - ('is_active', models.BooleanField(help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active', default=True)), - ('date_joined', models.DateTimeField(verbose_name='date joined', default=django.utils.timezone.now)), - ('groups', models.ManyToManyField(related_name='user_set', blank=True, verbose_name='groups', to='auth.Group', help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_query_name='user')), - ('user_permissions', models.ManyToManyField(related_name='user_set', blank=True, verbose_name='user permissions', to='auth.Permission', help_text='Specific permissions for this user.', related_query_name='user')), - ('name', models.CharField(max_length=255, verbose_name='Name of User', blank=True)), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, unique=True, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.')], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=30, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('name', models.CharField(blank=True, max_length=255, verbose_name='Name of User')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), ], options={ - 'verbose_name': 'user', 'abstract': False, + 'verbose_name': 'user', 'verbose_name_plural': 'users', }, managers=[ - (b'objects', django.contrib.auth.models.UserManager()), + ('objects', django.contrib.auth.models.UserManager()), ], ), ] From e953fda8dfe043ce9984513fd86b9021d7666f5f Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Fri, 23 Sep 2016 01:29:10 -0300 Subject: [PATCH 20/31] fix documentation about contrib/sites migrations --- docs/faq.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/faq.rst b/docs/faq.rst index 854e9ddd..def4ba1f 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -8,9 +8,9 @@ Why is there a django.contrib.sites directory in Cookiecutter Django? It is there to add a migration so you don't have to manually change the ``sites.Site`` record from ``example.com`` to whatever your domain is. Instead, your ``{{cookiecutter.domain_name}}`` and {{cookiecutter.project_name}} value is placed by **Cookiecutter** in the domain and name fields respectively. -See `0002_set_site_domain_and_name.py`_. +See `0003_set_site_domain_and_name.py`_. -.. _`0002_set_site_domain_and_name.py`: https://github.com/pydanny/cookiecutter-django/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/%7B%7Bcookiecutter.project_slug%7D%7D/contrib/sites/migrations/0002_set_site_domain_and_name.py +.. _`0003_set_site_domain_and_name.py`: https://github.com/pydanny/cookiecutter-django/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/%7B%7Bcookiecutter.project_slug%7D%7D/contrib/sites/migrations/0003_set_site_domain_and_name.py Why aren't you using just one configuration file (12-Factor App) From 97febbf8b4a9efd47ad923b63c38b6e66db016f2 Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Fri, 23 Sep 2016 01:32:41 -0300 Subject: [PATCH 21/31] removed django-autoslug until it's ready for 1.10 --- requirements_to_watch.txt | 2 ++ {{cookiecutter.project_slug}}/requirements/base.txt | 1 - .../users/migrations/0001_initial.py | 12 ++++++------ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/requirements_to_watch.txt b/requirements_to_watch.txt index 3e25cb20..34f0fe62 100644 --- a/requirements_to_watch.txt +++ b/requirements_to_watch.txt @@ -1,2 +1,4 @@ # These requirements prevented an upgrade to Django 1.10. django-coverage-plugin==1.3.1 +django-autoslug==1.9.3 + diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 13378d8f..df90ba07 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -40,7 +40,6 @@ psycopg2==2.6.2 # Unicode slugification awesome-slugify==1.6.5 -django-autoslug==1.9.3 # Time zones support pytz==2016.6.1 diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py index 626e10f3..e76c333f 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.9 on 2016-09-23 04:10 +# Generated by Django 1.10.1 on 2016-09-23 04:36 from __future__ import unicode_literals import django.contrib.auth.models -import django.core.validators +import django.contrib.auth.validators from django.db import migrations, models import django.utils.timezone @@ -13,7 +13,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('auth', '0007_alter_validators_add_error_messages'), + ('auth', '0008_alter_user_username_max_length'), ] operations = [ @@ -24,7 +24,7 @@ class Migration(migrations.Migration): ('password', models.CharField(max_length=128, verbose_name='password')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, unique=True, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.')], verbose_name='username')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), ('last_name', models.CharField(blank=True, max_length=30, verbose_name='last name')), ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), @@ -36,9 +36,9 @@ class Migration(migrations.Migration): ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), ], options={ - 'abstract': False, - 'verbose_name': 'user', 'verbose_name_plural': 'users', + 'verbose_name': 'user', + 'abstract': False, }, managers=[ ('objects', django.contrib.auth.models.UserManager()), From e9fc2f0582dfe2579e5e15920c917999bbd801fc Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Wed, 28 Sep 2016 23:58:39 -0300 Subject: [PATCH 22/31] update django-redis and whitenoise version --- {{cookiecutter.project_slug}}/requirements/base.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index df90ba07..b2abd4ed 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -12,7 +12,7 @@ django==1.10.1 # Configuration django-environ==0.4.0 {% if cookiecutter.use_whitenoise == 'y' -%} -whitenoise==3.2.1 +whitenoise==3.2.2 {%- endif %} @@ -45,8 +45,8 @@ awesome-slugify==1.6.5 pytz==2016.6.1 # Redis support -django-redis==4.4.4 -redis>=2.10.0 +django-redis==4.5.0 +redis>=2.10.5 {% if cookiecutter.use_celery == "y" %} celery==3.1.23 From 8f045fc08c36e518357c531b88b0154d922c8bf7 Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Thu, 29 Sep 2016 01:07:40 -0300 Subject: [PATCH 23/31] update jquery to 3.1.1 --- .../{{cookiecutter.project_slug}}/templates/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html index 94f9ef9f..e816a208 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html @@ -90,7 +90,7 @@ {% block javascript %} - + From 8fca0e0154b44dabf8d41739e448597d44d22317 Mon Sep 17 00:00:00 2001 From: "Fabio C. Barrioneuvo da Luz" Date: Thu, 29 Sep 2016 01:08:24 -0300 Subject: [PATCH 24/31] update README and CHANGELOG --- CHANGELOG.md | 17 +++++++++++++++-- README.rst | 6 +++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30851f24..22bf18f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,22 @@ All enhancements and patches to Cookiecutter Django will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -##[2016-09-22] +##[2016-09-28] ### Added -- New setting MAILGUN_SENDER_DOMAIN to allow sending mail from any domain other than those registered with mailgun (@jangeador) +- Added add default `AUTH_PASSWORD_VALIDATORS` configuration, generated by django 1.10 startproject. See (Password Validation docs)[https://docs.djangoproject.com/en/1.10/topics/auth/passwords/#module-django.contrib.auth.password_validation] (@luzfcb) +- Rename `MIDDLEWARE_CLASSES` to `MIDDLEWARE` to enable support to [new style middleware](https://github.com/django/deps/blob/master/final/0005-improved-middleware.rst) introduced in Django 1.10 (@luzfcb) +- New setting `MAILGUN_SENDER_DOMAIN` to allow sending mail from any domain other than those registered with mailgun (@jangeador) +### Changed +- Upgrade to Django 1.10.1 (@luzfcb) +- Upgrade django-model-utils to 2.6, django-redis to 4.5.0, redis to 2.10.5, Sphinx to 1.4.6, pytest-django to 3.0.0, django-anymail to 0.5, raven to 5.27.1 (@luzfcb) +- Upgrade to Bootstrap 4 Alpha 4, jQuery to 3.1.1, tether.js to 1.3.7 (@luzfcb) +- Update `manage.py` to use same code of `manage.py` from Django 1.10 (@luzfcb) +- Sync `sites` app migrations with django 1.10, and fix aditional migrations to `sites` and `user` app (@luzfcb) +d changed 'admin' url on `config/urls.py`, to stay the same as generated by django 1.10 (@luzfcb) +- Make test_docker.sh tests pass by passing new password auth rules (@ssteinerx) +### Removed +- Removed django-autoslug because not support django 1.10 at this date (@luzfcb) + ##[2016-09-10] ### Changed diff --git a/README.rst b/README.rst index b129a215..e9980f7b 100644 --- a/README.rst +++ b/README.rst @@ -26,9 +26,9 @@ Powered by Cookiecutter_, Cookiecutter Django is a framework for jumpstarting pr Features --------- -* For Django 1.9 +* For Django 1.10 * Renders Django projects with 100% starting test coverage -* Twitter Bootstrap_ v4.0.0 - `alpha 3`_ +* Twitter Bootstrap_ v4.0.0 - `alpha 4`_ * 12-Factor_ based settings via django-environ_ * Optimized development and production settings * Registration via django-allauth_ @@ -56,7 +56,7 @@ Optional Integrations * Integration with Sentry_ for error logging * Integration with Opbeat_ for performance monitoring -.. _`alpha 3`: http://blog.getbootstrap.com/2016/07/27/bootstrap-4-alpha-3/ +.. _`alpha 4`: http://blog.getbootstrap.com/2016/09/05/bootstrap-4-alpha-4/ .. _Bootstrap: https://github.com/twbs/bootstrap .. _django-environ: https://github.com/joke2k/django-environ .. _12-Factor: http://12factor.net/ From 42f94cdd865723db97d202ae1ad5f5fa41774612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20C=2E=20Barrionuevo=20da=20Luz?= Date: Thu, 29 Sep 2016 01:24:51 -0300 Subject: [PATCH 25/31] fix CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22bf18f0..46e0b38b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Added add default `AUTH_PASSWORD_VALIDATORS` configuration, generated by django 1.10 startproject. See (Password Validation docs)[https://docs.djangoproject.com/en/1.10/topics/auth/passwords/#module-django.contrib.auth.password_validation] (@luzfcb) - Rename `MIDDLEWARE_CLASSES` to `MIDDLEWARE` to enable support to [new style middleware](https://github.com/django/deps/blob/master/final/0005-improved-middleware.rst) introduced in Django 1.10 (@luzfcb) - New setting `MAILGUN_SENDER_DOMAIN` to allow sending mail from any domain other than those registered with mailgun (@jangeador) + ### Changed - Upgrade to Django 1.10.1 (@luzfcb) - Upgrade django-model-utils to 2.6, django-redis to 4.5.0, redis to 2.10.5, Sphinx to 1.4.6, pytest-django to 3.0.0, django-anymail to 0.5, raven to 5.27.1 (@luzfcb) @@ -15,6 +16,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Sync `sites` app migrations with django 1.10, and fix aditional migrations to `sites` and `user` app (@luzfcb) d changed 'admin' url on `config/urls.py`, to stay the same as generated by django 1.10 (@luzfcb) - Make test_docker.sh tests pass by passing new password auth rules (@ssteinerx) + ### Removed - Removed django-autoslug because not support django 1.10 at this date (@luzfcb) From 665c890db52b57327c1b3abea6a6ecdbe038c033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20C=2E=20Barrionuevo=20da=20Luz?= Date: Thu, 29 Sep 2016 01:25:15 -0300 Subject: [PATCH 26/31] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46e0b38b..290d805b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All enhancements and patches to Cookiecutter Django will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -##[2016-09-28] +##[2016-09-29] ### Added - Added add default `AUTH_PASSWORD_VALIDATORS` configuration, generated by django 1.10 startproject. See (Password Validation docs)[https://docs.djangoproject.com/en/1.10/topics/auth/passwords/#module-django.contrib.auth.password_validation] (@luzfcb) - Rename `MIDDLEWARE_CLASSES` to `MIDDLEWARE` to enable support to [new style middleware](https://github.com/django/deps/blob/master/final/0005-improved-middleware.rst) introduced in Django 1.10 (@luzfcb) From dceb2438cfbe7f40424393cba7669f46570593a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20C=2E=20Barrionuevo=20da=20Luz?= Date: Thu, 29 Sep 2016 01:27:48 -0300 Subject: [PATCH 27/31] fix CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 290d805b..6bb0e1f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ##[2016-09-29] ### Added -- Added add default `AUTH_PASSWORD_VALIDATORS` configuration, generated by django 1.10 startproject. See (Password Validation docs)[https://docs.djangoproject.com/en/1.10/topics/auth/passwords/#module-django.contrib.auth.password_validation] (@luzfcb) +- Added add default `AUTH_PASSWORD_VALIDATORS` configuration, generated by django 1.10 startproject. See [Password Validation docs](https://docs.djangoproject.com/en/1.10/topics/auth/passwords/#module-django.contrib.auth.password_validation") (@luzfcb) - Rename `MIDDLEWARE_CLASSES` to `MIDDLEWARE` to enable support to [new style middleware](https://github.com/django/deps/blob/master/final/0005-improved-middleware.rst) introduced in Django 1.10 (@luzfcb) - New setting `MAILGUN_SENDER_DOMAIN` to allow sending mail from any domain other than those registered with mailgun (@jangeador) From ef020ecd3121d69a518cc517d6c82fdcbbee3333 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 28 Sep 2016 21:32:04 -0700 Subject: [PATCH 28/31] Update django-model-utils from 2.5.2 to 2.6 --- {{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 b2abd4ed..0c983013 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -21,7 +21,7 @@ django-braces==1.9.0 django-crispy-forms==1.6.0 # Models -django-model-utils==2.5.2 +django-model-utils==2.6 # Images Pillow==3.3.1 From 3872cd08c3790f08c6859847135e7079e6f42c5d Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 28 Sep 2016 21:32:13 -0700 Subject: [PATCH 29/31] Update raven from 5.27.0 to 5.27.1 --- {{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 88300ff7..827f3eeb 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -29,7 +29,7 @@ django-anymail==0.5 {% if cookiecutter.use_sentry_for_error_reporting == "y" -%} # Raven is the Sentry client # -------------------------- -raven==5.27.0 +raven==5.27.1 {%- endif %} {% if cookiecutter.use_opbeat == "y" -%} From 80c569e2c25cd47bbf906c9c94939484c20377f4 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 28 Sep 2016 21:32:53 -0700 Subject: [PATCH 30/31] Update pytest-django from 2.9.1 to 3.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 bc260ba5..7661a46a 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -12,5 +12,5 @@ django-debug-toolbar==1.5 # improved REPL ipdb==0.10.1 -pytest-django==2.9.1 +pytest-django==3.0.0 pytest-sugar==0.7.1 From b28fe19f3ab332f66a7d7abe2009fdfd009b8e35 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 28 Sep 2016 21:32:54 -0700 Subject: [PATCH 31/31] Update pytest-django from 2.9.1 to 3.0.0 --- {{cookiecutter.project_slug}}/requirements/test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/test.txt b/{{cookiecutter.project_slug}}/requirements/test.txt index b607cbc5..42ed08c5 100644 --- a/{{cookiecutter.project_slug}}/requirements/test.txt +++ b/{{cookiecutter.project_slug}}/requirements/test.txt @@ -13,5 +13,5 @@ django-test-plus==1.0.15 factory_boy==2.7.0 # pytest -pytest-django==2.9.1 +pytest-django==3.0.0 pytest-sugar==0.7.1