This commit is contained in:
Jannis Gebauer 2015-10-24 18:46:49 +02:00
commit 1f36ed3c8e
18 changed files with 229 additions and 121 deletions

View File

@ -2,6 +2,48 @@
All enhancements and patches to cookiecutter-django will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [2015-10-22]
### Removed
- Remove unnecessary .gitkeep in static/images/ (@audreyr)
## [2015-10-21]
### Changed
- TODO (@pydanny)
- TODO (@theskumar)
## [2015-10-19]
### Changed
- On Windows, don't install psycopg2 locally. Still install it in test/prod which are assumed to be Unix. (@audreyr)
## [2015-10-15]
### Changed
- Made `post_gen_hook` function to change secret keys in files more generic (@pydanny)
- Set cryptographically randomized value to `DJANGO_SECRET_KEY` in `env.example` (@pydanny)
## [2015-10-14]
### Added
- Documention of project options (@audreyr)
### Changed
- Added clarification on building for local or production (@MathijsHoogland)
- Whitespace correction in dev.yml (@MathijsHoogland)
## [2015-10-13]
### Changed
- Requirements update (@theskumar)
## [2015-10-11]
### Changed
- Fixed raven issue on development (#302) (@jazztpt )
## [2015-10-05]
### Changed
- Update version of Django, Pillow, hitchselenium, psutil (@luzfcb)
## [2015-10-04]
### Changed
- Remove stray closing tags and fix navbar margin in in base.html (@hairychris)
- Docker docs to be functional and more understandable (@audreyr)
## [2015-09-30]
### Changed
- Fixed Sentry logging with celery (@jayfk)

View File

@ -56,6 +56,9 @@ Code Contributors
* @kaidokert
* Raphael Pierzina / @hackebrot
* Alvaro [Andor] / @andor-pierdelacabeza
* Chris Franklin / @hairychris
* Anna Callahan / @jazztpt
* Mathijs Hoogland / @MathijsHoogland
\* Possesses commit rights

View File

@ -4,29 +4,28 @@ Getting Up and Running with Docker
.. index:: Docker
The steps below will get you up and running with a local development environment.
All of these commands assume you are in the root of your generated project.
Prerequisites
--------------
If you don't already have these installed, get them all by installing `Docker Toolbox`_.
* docker
* docker-machine
* docker-compose
* virtualbox
If you don't already have these installed, you can get them at:
.. _`Docker Toolbox`: https://github.com/docker/toolbox/releases
* https://github.com/docker/toolbox/releases
* https://www.virtualbox.org/wiki/Downloads
Create the Machine (Optional)
-------------------------------
Go to the Root of your Project
------------------------------
On Ubuntu you have native Docker, so you don't need to create a VM with
docker-machine to use it.
All of these commands assume you are in the root of your generated project.
Create the Machine
-------------------
::
However, on Mac/Windows/other systems without native Docker, you'll want to
start by creating a VM with docker-machine::
$ docker-machine create --driver virtualbox dev1
@ -34,29 +33,16 @@ Create the Machine
name them accordingly. Instead of 'dev1' you might have 'dev2', 'myproject',
'djangopackages', et al.
Make the new machine the active unit
-------------------------------------
This tells our computer that all future commands are specifically for the just
created machine. Using the ``eval`` command we can switch machines as needed.
::
$ eval "$(docker-machine env dev1)"
Get the IP Address
--------------------
Acquiring the IP Address is good for two reasons:
1. Confirms that the machine is up and running.
2. Tells us the IP address where our Django project is being served.
::
Once your machine is up and running, run this::
$ docker-machine ip dev1
123.456.789.012
This is also the IP address where the Django project will be served from.
Saving changes
--------------
@ -64,15 +50,12 @@ If you are using OS X or Windows, you need to create a /data partition inside th
virtual machine that runs the docker deamon in order make all changes persistent.
If you don't do that your /data directory will get wiped out on every reboot.
To create a persistent folder, log into the virtual machine by running:
::
To create a persistent folder, log into the virtual machine by running::
$ docker-machine ssh dev1
$ sudo su
$ echo 'ln -sfn /mnt/sda1/data /data' >> /var/lib/boot2docker/bootlocal.sh
In case you are wondering why you can't use a host volume to keep the files on
your mac: As of `boot2docker` 1.7 you'll run into permission problems with mounted
host volumes if the container creates his own user and chown's the directories
@ -83,57 +66,19 @@ Build the Stack
---------------
This can take a while, especially the first time you run this particular command
on your development system.
on your development system::
::
$ docker-compose -f dev.yml build
$ docker-compose build
If you want to build the production environment you don't have to pass an argument -f, it will automatically use docker-compose.yml.
Boot the System
------------------------------
---------------
This brings up both Django and PostgreSQL. The first time it is run it might
take a while to get started, but subsequent runs will occur quickly.
This brings up both Django and PostgreSQL.
::
$ docker-compose -f dev.yml up
If you want to run the entire system in production mode, then run:
::
$ docker-compose up
If you want to run the stack in detached mode (in the background), use the ``-d`` argument::
::
$ docker-compose up -d
Running bash commands (i.e. management commands)
----------------------------------------------------
This is done using the ``docker-compose run`` command. In the following examples
we specify the ``django`` container as the location to run our management commands.
Example:
$ docker-compose run django python manage.py migrate
$ docker-compose run django python manage.py createsuperuser
Deprecated
==========
**Note:** This segment of documentation is being kept in this location as part of our documentation transition process.
The steps below will get you up and running with a local development environment. We assume you have the following installed:
* docker
* docker-compose
The first time it is run it might take a while to get started, but subsequent
runs will occur quickly.
Open a terminal at the project root and run the following for local development::
@ -147,9 +92,42 @@ And then run::
$ docker-compose up
Running management commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As with any shell command that we wish to run in our container, this is done
using the ``docker-compose run`` command.
To migrate your app and to create a superuser, run::
$ docker-compose run django python manage.py migrate
$ docker-compose run django python manage.py createsuperuser
Here we specify the ``django`` container as the location to run our management commands.
Production Mode
~~~~~~~~~~~~~~~~
Instead of using `dev.yml`, you would use `docker-compose.yml`.
Other Useful Tips
------------------
Make a machine the active unit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This tells our computer that all future commands are specifically for the dev1 machine.
Using the ``eval`` command we can switch machines as needed.
::
$ eval "$(docker-machine env dev1)"
Detached Mode
~~~~~~~~~~~~~
If you want to run the stack in detached mode (in the background), use the ``-d`` argument:
::
$ docker-compose up -d

View File

@ -15,11 +15,9 @@ First make sure to create and activate a virtualenv_, then open a terminal at th
.. _virtualenv: http://docs.python-guide.org/en/latest/dev/virtualenvs/
Then, create a PostgreSQL database and add the database configuration using the ``dj-database-url`` app pattern: ``postgres://db_owner:password@dbserver_ip:port/db_name`` either:
* in the ``config.settings.common.py`` setting file,
* or in the environment variable ``DATABASE_URL``
Then, create a PostgreSQL database with the following command, where `[repo_name]` is what value you entered for your project's `repo_name`::
$ createdb [repo_name]
You can now run the usual Django ``migrate`` and ``runserver`` command::

View File

@ -15,6 +15,7 @@ Contents:
:maxdepth: 2
project-generation-options
developing-locally
developing-locally-docker
settings

View File

@ -0,0 +1,55 @@
Project Generation Options
==========================
project_name [project_name]:
Your human-readable project name, including any capitalization or spaces.
repo_name [project_name]:
The slug of your project, without dashes or spaces. Used to name your repo
and in other places where a Python-importable version of your project name
is needed.
author_name [Your Name]:
You! This goes into places like the LICENSE file.
email [Your email]:
Your email address.
description [A short description of the project.]
Used in the generated README.rst and other places.
domain_name [example.com]
Whatever domain name you plan to use for your project when it goes live.
version [0.1.0]
The starting version number for your project.
timezone [UTC]
Used in the common settings file for the `TIME_ZONE` value.
use_whitenoise [y]
Whether to use WhiteNoise_ for static file serving.
use_celery [n]
Whether to use Celery_. This gives you the ability to use distributed task
queues in your project.
use_maildump [n]
Whether to use Maildump_. Maildump is a tool that simulates email receiving
for development purposes. It runs a super simple SMTP server which catches
any message sent to it. Then messages are displayed in a web interface.
use_sentry [n]
Whether to use Sentry_ to log errors from your project.
windows [n]
Whether you'll be developing on Windows.
use_python2 [n]
By default, the Python code generated will be for Python 3.x. But if you
answer `y` here, it will be legacy Python 2.7 code.
.. _WhiteNoise: https://github.com/evansd/whitenoise
.. _Celery: https://github.com/celery/celery
.. _Maildump: https://github.com/ThiefMaster/maildump
.. _Sentry: https://github.com/getsentry/sentry

View File

@ -55,28 +55,43 @@ def get_random_string(
).digest())
return ''.join(random.choice(allowed_chars) for i in range(length))
def make_secret_key(project_directory):
"""Generates and saves random secret key"""
# Determine the local_setting_file_location
local_setting_file_location = os.path.join(
project_directory,
'config/settings/local.py'
)
def set_secret_key(setting_file_location):
# Open locals.py
with open(local_setting_file_location) as f:
local_py = f.read()
with open(setting_file_location) as f:
file_ = f.read()
# Generate a SECRET_KEY that matches the Django standard
SECRET_KEY = get_random_string()
SECRET_KEY = 'CHANGEME!!!' + SECRET_KEY
# Replace "CHANGEME!!!" with SECRET_KEY
local_py = local_py.replace('CHANGEME!!!', SECRET_KEY)
file_ = file_.replace('CHANGEME!!!', SECRET_KEY)
# Write the results to the locals.py module
with open(local_setting_file_location, 'w') as f:
f.write(local_py)
with open(setting_file_location, 'w') as f:
f.write(file_)
def make_secret_key(project_directory):
"""Generates and saves random secret key"""
# Determine the local_setting_file_location
local_setting = os.path.join(
project_directory,
'config/settings/local.py'
)
# local.py settings file
set_secret_key(local_setting)
env_file = os.path.join(
project_directory,
'env.example'
)
# env.example file
set_secret_key(env_file)
def remove_task_app(project_directory):
"""Removes the taskapp if celery isn't going to be used"""

View File

@ -13,7 +13,6 @@ indent_style = space
indent_size = 4
[*.py]
# https://github.com/timothycrosley/isort/wiki/isort-Settings
line_length=120
known_first_party={{ cookiecutter.repo_name }}
multi_line_output=3

View File

@ -1,4 +1,3 @@
postgres:
image: postgres
volumes:

View File

@ -3,8 +3,8 @@ POSTGRES_USER=postgresuser
ADMIN_URL=
DJANGO_SETTINGS_MODULE=config.settings.production
DJANGO_SECRET_KEY=
DJANGO_ALLOWED_HOSTS=
DJANGO_SECRET_KEY=CHANGEME!!!
DJANGO_ALLOWED_HOSTS=.{{ cookiecutter.domain_name }}
DJANGO_AWS_ACCESS_KEY_ID=
DJANGO_AWS_SECRET_ACCESS_KEY=
DJANGO_AWS_STORAGE_BUCKET_NAME=

View File

@ -1,5 +1,5 @@
# Bleeding edge Django
django==1.8.4
django==1.8.5
# Configuration
django-environ==0.4.0
@ -18,18 +18,23 @@ django-floppyforms==1.5.2
django-model-utils==2.3.1
# Images
Pillow==2.9.0
Pillow==3.0.0
# For user registration, either via email or social
# Well-built with regular release cycles!
django-allauth==0.23.0
# For the persistence stores
{% if cookiecutter.windows == 'y' -%}
# On Windows, you must download/install psycopg2 manually
# from http://www.lfd.uci.edu/~gohlke/pythonlibs/#psycopg
{% else %}
# Python-PostgreSQL Database Adapter
psycopg2==2.6.1
{%- endif %}
# Unicode slugification
unicode-slugify==0.1.3
django-autoslug==1.8.0
django-autoslug==1.9.3
# Time zones support
pytz==2015.6

View File

@ -1,21 +1,21 @@
# Local development dependencies go here
-r base.txt
coverage==4.0
coverage==4.0.1
Sphinx
django-extensions==1.5.7
Werkzeug==0.10.4
django-test-plus==1.0.9
factory_boy==2.5.2
factory_boy==2.6.0
# django-debug-toolbar that works with Django 1.5+
django-debug-toolbar==1.3.2
django-debug-toolbar==1.4
# improved REPL
ipdb==0.8.1
{% if cookiecutter.use_maildump == "y" -%}
# Required by maildump. Need to pin dependency to gevent beta to be Python 3-compatible.
gevent==1.1b5
gevent==1.0.2
# Enables better email testing
maildump==0.5.1
{%- endif %}

View File

@ -2,6 +2,13 @@
# production that isn't in development.
-r base.txt
{% if cookiecutter.windows == 'y' -%}
# Python-PostgreSQL Database Adapter
# If using Win for dev, this assumes Unix in prod
# ------------------------------------------------
psycopg2==2.6.1
{%- endif %}
# WSGI Handler
# ------------------------------------------------
gevent==1.0.2

View File

@ -1,5 +1,12 @@
# Test dependencies go here.
-r base.txt
{% if cookiecutter.windows == 'y' -%}
# Python-PostgreSQL Database Adapter
# If using Win for dev, this assumes Unix in test/prod
psycopg2==2.6.1
{%- endif %}
coverage==4.0
flake8==2.4.1
django-test-plus==1.0.9

View File

@ -5,7 +5,7 @@ hitchcron==0.2
hitchpostgres==0.6.3
hitchpython==0.3.8
hitchredis==0.4.3
hitchselenium==0.4.3
hitchselenium==0.4.5
hitchserve==0.4.5
hitchsmtp==0.2.1
hitchtest==0.8.0
@ -14,7 +14,7 @@ ipython==4.0.0
Jinja2==2.8
MarkupSafe==0.23
patool==1.8
psutil==3.2.1
psutil==3.2.2
python-build==0.2.3
pyuv==1.2.0
PyYAML==3.11

View File

@ -4,10 +4,7 @@ import os
from celery import Celery
from django.apps import AppConfig
from django.conf import settings
{% if cookiecutter.use_sentry == "y" -%}
from raven import Client
from raven.contrib.celery import register_signal
{%- endif %}
if not settings.configured:
# set the default Django settings module for the 'celery' program.
@ -30,6 +27,8 @@ class CeleryConfig(AppConfig):
{% if cookiecutter.use_sentry == "y" -%}
if hasattr(settings, 'RAVEN_CONFIG'):
# Celery signal registration
from raven import Client
from raven.contrib.celery import register_signal
client = Client(dsn=settings.RAVEN_CONFIG['dsn'])
register_signal(client)
{%- endif %}

View File

@ -31,7 +31,7 @@
<body>
<div class="m-b-lg">
<div class="m-b">
<nav class="navbar navbar-dark navbar-static-top bg-inverse">
<div class="container">
<a class="navbar-brand" href="/">{% endraw %}{{ cookiecutter.project_name }}{% raw %}</a>
@ -42,17 +42,17 @@
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-toggleable-xs" id="bs-navbar-collapse-1">
<nav class="nav navbar-nav">
<a class="nav-link nav-item" href="{% url 'home' %}">Home</a></li>
<a class="nav-link nav-item" href="{% url 'about' %}">About</a></li>
<a class="nav-link nav-item" href="{% url 'home' %}">Home</a>
<a class="nav-link nav-item" href="{% url 'about' %}">About</a>
</nav>
<nav class="nav navbar-nav pull-right">
{% if request.user.is_authenticated %}
<a class="nav-link nav-item" href="{% url 'users:detail' request.user.username %}">{% trans "My Profile" %}</a></li>
<a class="nav-link nav-item" href="{% url 'account_logout' %}">{% trans "Logout" %}</a></li>
<a class="nav-link nav-item" href="{% url 'users:detail' request.user.username %}">{% trans "My Profile" %}</a>
<a class="nav-link nav-item" href="{% url 'account_logout' %}">{% trans "Logout" %}</a>
{% else %}
<a class="nav-link nav-item" href="{% url 'account_signup' %}">{% trans "Sign Up" %}</a></li>
<a class="nav-link nav-item" href="{% url 'account_login' %}">{% trans "Log In" %}</a></li>
<a class="nav-link nav-item" href="{% url 'account_signup' %}">{% trans "Sign Up" %}</a>
<a class="nav-link nav-item" href="{% url 'account_login' %}">{% trans "Log In" %}</a>
{% endif %}
</nav>
</div>