mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2024-11-28 12:34:01 +03:00
Merge commit '9263297952740423f6baf2ec2ac58bc470a99a75'
This commit is contained in:
commit
27307c2ef5
|
@ -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/).
|
||||
|
||||
## [2018-01-15]
|
||||
### Changed
|
||||
- Removed Elastic Beanstalk support (@pydanny)
|
||||
|
||||
## [2017-12-28]
|
||||
### Changed
|
||||
- Upgraded to Django 1.11 (@pydanny)
|
||||
|
|
|
@ -36,13 +36,12 @@ To run all tests using various versions of python in virtualenvs defined in tox.
|
|||
|
||||
$ tox
|
||||
|
||||
It is possible to tests with some versions of python, to do this the command
|
||||
It is possible to test with a specific version of python. To do this, the command
|
||||
is::
|
||||
|
||||
$ tox -e py34,py35
|
||||
$ tox -e py36
|
||||
|
||||
Will run py.test with the python3.4, and python3.5 interpreters, for
|
||||
example.
|
||||
This will run py.test with the python3.6 interpreter, for example.
|
||||
|
||||
To run a particular test with tox for against your current Python version::
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ Core Developers
|
|||
These contributors have commit flags for the repository,
|
||||
and are able to accept and merge pull requests.
|
||||
|
||||
=========================== ============= ===========
|
||||
=========================== ================ ===========
|
||||
Name Github Twitter
|
||||
=========================== ============= ===========
|
||||
=========================== ================ ===========
|
||||
Daniel Roy Greenfeld `@pydanny`_ @pydanny
|
||||
Audrey Roy Greenfeld* `@audreyr`_ @audreyr
|
||||
Fábio C. Barrionuevo da Luz `@luzfcb`_ @luzfcb
|
||||
|
@ -17,7 +17,8 @@ Saurabh Kumar `@theskumar`_ @_theskumar
|
|||
Jannis Gebauer `@jayfk`_
|
||||
Burhan Khalid `@burhan`_ @burhan
|
||||
Shupeyko Nikita `@webyneter`_ @webyneter
|
||||
=========================== ============= ===========
|
||||
Bruno Alla `@browniebroke`_ @_BrunoAlla
|
||||
=========================== ================ ===========
|
||||
|
||||
*Audrey is also the creator of Cookiecutter. Audrey and
|
||||
Daniel are on the Cookiecutter core team.*
|
||||
|
@ -28,6 +29,7 @@ Daniel are on the Cookiecutter core team.*
|
|||
.. _@audreyr: https://github.com/audreyr
|
||||
.. _@jayfk: https://github.com/jayfk
|
||||
.. _@webyneter: https://github.com/webyneter
|
||||
.. _@browniebroke: https://github.com/browniebroke
|
||||
|
||||
Other Contributors
|
||||
------------------
|
||||
|
@ -64,7 +66,6 @@ Listed in alphabetical order.
|
|||
Bo Lopker `@blopker`_
|
||||
Bouke Haarsma
|
||||
Brent Payne `@brentpayne`_ @brentpayne
|
||||
Bruno Alla `@browniebroke`_ @_BrunoAlla
|
||||
Burhan Khalid `@burhan`_ @burhan
|
||||
Catherine Devlin `@catherinedevlin`_
|
||||
Cédric Gaspoz `@cgaspoz`_
|
||||
|
@ -171,7 +172,6 @@ Listed in alphabetical order.
|
|||
.. _@bloodpet: https://github.com/bloodpet
|
||||
.. _@blopker: https://github.com/blopker
|
||||
.. _@bogdal: https://github.com/bogdal
|
||||
.. _@browniebroke: https://github.com/browniebroke
|
||||
.. _@burhan: https://github.com/burhan
|
||||
.. _@c-rhodes: https://github.com/c-rhodes
|
||||
.. _@caffodian: https://github.com/caffodian
|
||||
|
@ -228,7 +228,6 @@ Listed in alphabetical order.
|
|||
.. _@rm--: https://github.com/rm--
|
||||
.. _@romanosipenko: https://github.com/romanosipenko
|
||||
.. _@shireenrao: https://github.com/shireenrao
|
||||
.. _@webyneter: https://github.com/webyneter
|
||||
.. _@show0k: https://github.com/show0k
|
||||
.. _@sfdye: https://github.com/sfdye
|
||||
.. _@shultz: https://github.com/shultz
|
||||
|
@ -240,7 +239,7 @@ Listed in alphabetical order.
|
|||
.. _@timfreund: https://github.com/timfreund
|
||||
.. _@Travistock: https://github.com/Tavistock
|
||||
.. _@trungdong: https://github.com/trungdong
|
||||
.. _@viviangb: httpsL//github.com/viviangb
|
||||
.. _@viviangb: https://github.com/viviangb
|
||||
.. _@xpostudio4: https://github.com/xpostudio4
|
||||
.. _@yunti: https://github.com/yunti
|
||||
.. _@zcho: https://github.com/zcho
|
||||
|
@ -250,6 +249,12 @@ Listed in alphabetical order.
|
|||
.. _@jangeador: https://github.com/jangeador
|
||||
.. _@townie: https://github.com/townie
|
||||
.. _@MightySCollins: https://github.com/MightySCollins
|
||||
.. _@dadokkio: https://github.com/dadokkio
|
||||
.. _@bwarren2: https://github.com/bwarren2
|
||||
.. _@bertdemiranda: https://github.com/bertdemiranda
|
||||
.. _@brentpayne: https://github.com/brentpayne
|
||||
.. _@afrowave: https://github.com/afrowave
|
||||
.. _@pchiquet: https://github.com/pchiquet
|
||||
|
||||
Special Thanks
|
||||
~~~~~~~~~~~~~~
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2013-2016, Daniel Greenfeld
|
||||
Copyright (c) 2013-2018, Daniel Greenfeld
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
30
README.rst
30
README.rst
|
@ -12,6 +12,10 @@ Cookiecutter Django
|
|||
.. image:: https://badges.gitter.im/Join Chat.svg
|
||||
:target: https://gitter.im/pydanny/cookiecutter-django?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
||||
|
||||
.. image:: https://www.codetriage.com/pydanny/cookiecutter-django/badges/users.svg
|
||||
:target: https://www.codetriage.com/pydanny/cookiecutter-django
|
||||
:alt: Code Helpers Badge
|
||||
|
||||
Powered by Cookiecutter_, Cookiecutter Django is a framework for jumpstarting
|
||||
production-ready Django projects quickly.
|
||||
|
||||
|
@ -51,7 +55,6 @@ Features
|
|||
* Instructions for deploying to PythonAnywhere_
|
||||
* Run tests with unittest or py.test
|
||||
* Customizable PostgreSQL version
|
||||
* Experimental support for Amazon Elastic Beanstalk
|
||||
|
||||
.. _`maintained Foundation fork`: https://github.com/Parbhat/cookiecutter-django-foundation
|
||||
|
||||
|
@ -168,16 +171,19 @@ Answer the prompts with your own desired options_. For example::
|
|||
use_heroku [n]: y
|
||||
use_compressor [n]: y
|
||||
Select postgresql_version:
|
||||
1 - 9.5
|
||||
2 - 9.4
|
||||
3 - 9.3
|
||||
4 - 9.2
|
||||
1 - 10
|
||||
2 - 9.6
|
||||
3 - 9.5
|
||||
4 - 9.4
|
||||
5 - 9.3
|
||||
6 - 9.2
|
||||
Choose from 1, 2, 3, 4 [1]: 1
|
||||
Select js_task_runner:
|
||||
1 - Gulp
|
||||
2 - Grunt
|
||||
3 - None
|
||||
Choose from 1, 2, 3, 4 [1]: 1
|
||||
custom_bootstrap_compilation [n]: n
|
||||
Select open_source_license:
|
||||
1 - MIT
|
||||
2 - BSD
|
||||
|
@ -185,7 +191,6 @@ 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::
|
||||
|
||||
|
@ -222,7 +227,7 @@ Community
|
|||
.. _`issue`: https://github.com/pydanny/cookiecutter-django/issues
|
||||
.. _`Gitter`: https://gitter.im/pydanny/cookiecutter-django?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
||||
|
||||
For Readers of Two Scoops of Django 1.8
|
||||
For Readers of Two Scoops of Django
|
||||
--------------------------------------------
|
||||
|
||||
You may notice that some elements of this project do not exactly match what we describe in chapter 3. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored.
|
||||
|
@ -274,14 +279,21 @@ experience better.
|
|||
Articles
|
||||
---------
|
||||
|
||||
* `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
|
||||
* `Django and GitLab - Running Continuous Integration and tests with your FREE account`_ - May. 11, 2016
|
||||
* `Development and Deployment of Cookiecutter-Django on Fedora`_ - Jan. 18, 2016
|
||||
* `Development and Deployment of Cookiecutter-Django via Docker`_ - Dec. 29, 2015
|
||||
* `How to create a Django Application using Cookiecutter and Django 1.8`_ - Sept. 12, 2015
|
||||
* `Introduction to Cookiecutter-Django`_ - Feb. 19, 2016
|
||||
* `Django and GitLab - Running Continuous Integration and tests with your FREE account`_ - May. 11, 2016
|
||||
|
||||
Have a blog or online publication? Write about your cookiecutter-django tips and tricks, then send us a pull request with the link.
|
||||
|
||||
.. _`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/
|
||||
|
||||
.. _`Development and Deployment of Cookiecutter-Django via Docker`: https://realpython.com/blog/python/development-and-deployment-of-cookiecutter-django-via-docker/
|
||||
.. _`Development and Deployment of Cookiecutter-Django on Fedora`: https://realpython.com/blog/python/development-and-deployment-of-cookiecutter-django-on-fedora/
|
||||
.. _`How to create a Django Application using Cookiecutter and Django 1.8`: https://www.swapps.io/blog/how-to-create-a-django-application-using-cookiecutter-and-django-1-8/
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
"windows": "n",
|
||||
"use_docker": "n",
|
||||
"use_heroku": "n",
|
||||
"use_elasticbeanstalk_experimental": "n",
|
||||
"use_compressor": "n",
|
||||
"postgresql_version": ["10", "9.6", "9.5", "9.4", "9.3", "9.2"],
|
||||
"js_task_runner": ["Gulp", "Grunt", "None"],
|
||||
|
|
|
@ -35,7 +35,7 @@ Make sure your project is fully commited and pushed up to Bitbucket or Github or
|
|||
|
||||
git clone <my-repo-url> # you can also use hg
|
||||
cd my-project-name
|
||||
mkvirtualenv --python=/usr/bin/python3.5 my-project-name
|
||||
mkvirtualenv --python=/usr/bin/python3.6 my-project-name
|
||||
pip install -r requirements/production.txt # may take a few minutes
|
||||
|
||||
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
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
|
||||
-------------
|
||||
|
||||
If you haven't done so, create a directory of environments::
|
||||
|
||||
eb init -p python3.4 MY_PROJECT_SLUG
|
||||
# Warning: If you use python3.6, you will run into problems later due to some incompatibility with
|
||||
# mod_wgsi 3.5 (packaged in 64bit Amazon Linux 2017.09 v2.6.1 running Python 3.6). See:
|
||||
# https://serverfault.com/questions/884469/mod-wsgi-call-to-site-addsitedir-failed-on-aws-elastic-beanstalk-python-3/885445
|
||||
|
||||
Replace `MY_PROJECT_SLUG` with the value you entered for `project_slug`.
|
||||
|
||||
Once that is done, create the environment (server) where the app will run::
|
||||
|
||||
eb create MY_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
|
||||
|
||||
If you are not in the right environment, then put yourself in the correct one::
|
||||
|
||||
eb use MY_PROJECT_SLUG
|
||||
|
||||
Set the environment variables. Notes: You will be prompted if the `.env` file is missing. The script will ignore any PostgreSQL values, as RDS uses it's own system::
|
||||
|
||||
# Set the environment variables
|
||||
python ebsetenv.py
|
||||
|
||||
Speaking of PostgreSQL, go to the Elasting Beanstalk configuration panel for RDS. Create new RDS database, with these attributes:
|
||||
|
||||
* PostgreSQL
|
||||
* Version 9.4.9
|
||||
* Size db.t2.micro (You can upgrade later)
|
||||
|
||||
(Get some coffee, this is going to take a while)
|
||||
|
||||
Once you have a database specified, deploy again so your instance can pick up the new PostgreSQL values::
|
||||
|
||||
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) 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.
|
|
@ -25,7 +25,6 @@ Contents:
|
|||
faq
|
||||
troubleshooting
|
||||
my-favorite-cookie
|
||||
deployment-with-elastic-beanstalk
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
|
|
@ -73,7 +73,9 @@ js_task_runner [1]
|
|||
3. None
|
||||
|
||||
custom_bootstrap_compilation [n]
|
||||
If you use Grunt, scaffold out recompiling Bootstrap as as task. (Useful for letting you change Bootstrap variables in real time.) Consult project README for more details.
|
||||
Scaffold out recompiling Bootstrap as as task, with Gulp_ or Grunt_.
|
||||
Useful for letting you change Bootstrap variables in real time.
|
||||
Consult project README for more details.
|
||||
|
||||
open_source_license [1]
|
||||
Select a software license for the project. The choices are:
|
||||
|
|
|
@ -22,7 +22,7 @@ DJANGO_ADMIN_URL n/a r'^admin/'
|
|||
DJANGO_CACHES CACHES (default) locmem redis
|
||||
DJANGO_DATABASES DATABASES (default) See code See code
|
||||
DJANGO_DEBUG DEBUG True False
|
||||
DJANGO_SECRET_KEY SECRET_KEY CHANGEME!!! raises error
|
||||
DJANGO_SECRET_KEY SECRET_KEY !!!SET DJANGO_SECRET_KEY!!! raises error
|
||||
DJANGO_SECURE_BROWSER_XSS_FILTER SECURE_BROWSER_XSS_FILTER n/a True
|
||||
DJANGO_SECURE_SSL_REDIRECT SECURE_SSL_REDIRECT n/a True
|
||||
DJANGO_SECURE_CONTENT_TYPE_NOSNIFF SECURE_CONTENT_TYPE_NOSNIFF n/a True
|
||||
|
|
|
@ -1,273 +1,283 @@
|
|||
"""
|
||||
Does the following:
|
||||
NOTE:
|
||||
the below code is to be maintained Python 2.x-compatible
|
||||
as the whole Cookiecutter Django project initialization
|
||||
can potentially be run in Python 2.x environment
|
||||
(at least so we presume in `pre_gen_project.py`).
|
||||
|
||||
1. Generates and saves random secret key
|
||||
2. Removes the taskapp if celery isn't going to be used
|
||||
3. Removes the .idea directory if PyCharm isn't going to be used
|
||||
4. Copy files from /docs/ to {{ cookiecutter.project_slug }}/docs/
|
||||
|
||||
TODO: this might have to be moved to a pre_gen_hook
|
||||
|
||||
A portion of this code was adopted from Django's standard crypto functions and
|
||||
utilities, specifically:
|
||||
https://github.com/django/django/blob/master/django/utils/crypto.py
|
||||
TODO: ? restrict Cookiecutter Django project initialization to Python 3.x environments only
|
||||
"""
|
||||
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
import string
|
||||
import sys
|
||||
|
||||
# Get the root project directory
|
||||
PROJECT_DIRECTORY = os.path.realpath(os.path.curdir)
|
||||
|
||||
# Use the system PRNG if possible
|
||||
try:
|
||||
# Inspired by
|
||||
# https://github.com/django/django/blob/master/django/utils/crypto.py
|
||||
random = random.SystemRandom()
|
||||
using_sysrandom = True
|
||||
except NotImplementedError:
|
||||
using_sysrandom = False
|
||||
|
||||
|
||||
def get_random_string(length=50):
|
||||
"""
|
||||
Returns a securely generated random string.
|
||||
The default length of 12 with the a-z, A-Z, 0-9 character set returns
|
||||
a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
|
||||
"""
|
||||
punctuation = string.punctuation.replace('"', '').replace("'", '')
|
||||
punctuation = punctuation.replace('\\', '')
|
||||
if using_sysrandom:
|
||||
return ''.join(random.choice(
|
||||
string.digits + string.ascii_letters + punctuation
|
||||
) for i in range(length))
|
||||
|
||||
print(
|
||||
"Cookiecutter Django couldn't find a secure pseudo-random number generator on your system."
|
||||
" Please change change your SECRET_KEY variables in conf/settings/local.py and env.example"
|
||||
" manually."
|
||||
)
|
||||
return "CHANGEME!!"
|
||||
PROJECT_DIR_PATH = os.path.realpath(os.path.curdir)
|
||||
|
||||
|
||||
def set_secret_key(setting_file_location):
|
||||
# Open locals.py
|
||||
with open(setting_file_location) as f:
|
||||
file_ = f.read()
|
||||
|
||||
# Generate a SECRET_KEY that matches the Django standard
|
||||
SECRET_KEY = get_random_string()
|
||||
|
||||
# Replace "CHANGEME!!!" with SECRET_KEY
|
||||
file_ = file_.replace('CHANGEME!!!', SECRET_KEY, 1)
|
||||
|
||||
# Write the results to the locals.py module
|
||||
with open(setting_file_location, 'w') as f:
|
||||
f.write(file_)
|
||||
def remove_file(file_path):
|
||||
if os.path.exists(file_path):
|
||||
os.remove(file_path)
|
||||
|
||||
|
||||
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_open_source_project_only_files():
|
||||
file_names = [
|
||||
'CONTRIBUTORS.txt',
|
||||
]
|
||||
for file_name in file_names:
|
||||
os.remove(os.path.join(PROJECT_DIR_PATH, file_name))
|
||||
|
||||
|
||||
def remove_file(file_name):
|
||||
if os.path.exists(file_name):
|
||||
os.remove(file_name)
|
||||
def remove_gplv3_files():
|
||||
file_names = [
|
||||
'COPYING',
|
||||
]
|
||||
for file_name in file_names:
|
||||
os.remove(os.path.join(PROJECT_DIR_PATH, file_name))
|
||||
|
||||
|
||||
def remove_task_app(project_directory):
|
||||
"""Removes the taskapp if celery isn't going to be used"""
|
||||
# Determine the local_setting_file_location
|
||||
task_app_location = os.path.join(
|
||||
PROJECT_DIRECTORY,
|
||||
'{{ cookiecutter.project_slug }}/taskapp'
|
||||
)
|
||||
shutil.rmtree(task_app_location)
|
||||
def remove_pycharm_files():
|
||||
idea_dir_path = os.path.join(PROJECT_DIR_PATH, '.idea')
|
||||
if os.path.exists(idea_dir_path):
|
||||
shutil.rmtree(idea_dir_path)
|
||||
|
||||
|
||||
def remove_pycharm_dir(project_directory):
|
||||
"""
|
||||
Removes directories related to PyCharm
|
||||
if it isn't going to be used
|
||||
"""
|
||||
idea_dir_location = os.path.join(PROJECT_DIRECTORY, '.idea/')
|
||||
if os.path.exists(idea_dir_location):
|
||||
shutil.rmtree(idea_dir_location)
|
||||
|
||||
docs_dir_location = os.path.join(PROJECT_DIRECTORY, 'docs/pycharm/')
|
||||
if os.path.exists(docs_dir_location):
|
||||
shutil.rmtree(docs_dir_location)
|
||||
|
||||
|
||||
def remove_heroku_files():
|
||||
"""
|
||||
Removes files needed for heroku if it isn't going to be used
|
||||
"""
|
||||
filenames = ["Procfile", "runtime.txt"]
|
||||
if '{{ cookiecutter.use_elasticbeanstalk_experimental }}'.lower() != 'y':
|
||||
filenames.append("requirements.txt")
|
||||
for filename in ["Procfile", "runtime.txt"]:
|
||||
file_name = os.path.join(PROJECT_DIRECTORY, filename)
|
||||
remove_file(file_name)
|
||||
docs_dir_path = os.path.join(PROJECT_DIR_PATH, 'docs', 'pycharm')
|
||||
if os.path.exists(docs_dir_path):
|
||||
shutil.rmtree(docs_dir_path)
|
||||
|
||||
|
||||
def remove_docker_files():
|
||||
"""
|
||||
Removes files needed for docker if it isn't going to be used
|
||||
"""
|
||||
for filename in ["local.yml", "production.yml", ".dockerignore"]:
|
||||
os.remove(os.path.join(
|
||||
PROJECT_DIRECTORY, filename
|
||||
))
|
||||
shutil.rmtree(os.path.join(PROJECT_DIR_PATH, 'compose'))
|
||||
|
||||
shutil.rmtree(os.path.join(
|
||||
PROJECT_DIRECTORY, "compose"
|
||||
))
|
||||
file_names = [
|
||||
'local.yml',
|
||||
'production.yml',
|
||||
'.dockerignore',
|
||||
]
|
||||
for file_name in file_names:
|
||||
os.remove(os.path.join(PROJECT_DIR_PATH, file_name))
|
||||
|
||||
|
||||
def remove_heroku_files():
|
||||
file_names = [
|
||||
'Procfile',
|
||||
'runtime.txt',
|
||||
]
|
||||
for file_name in file_names:
|
||||
remove_file(os.path.join(PROJECT_DIR_PATH, file_name))
|
||||
|
||||
|
||||
def remove_paas_files():
|
||||
none_paas_files_left = True
|
||||
|
||||
if '{{ cookiecutter.use_heroku }}'.lower() == 'n':
|
||||
remove_heroku_files()
|
||||
none_paas_files_left &= True
|
||||
else:
|
||||
none_paas_files_left &= False
|
||||
|
||||
if none_paas_files_left:
|
||||
remove_file(os.path.join(PROJECT_DIR_PATH, 'requirements.txt'))
|
||||
|
||||
|
||||
def remove_grunt_files():
|
||||
"""
|
||||
Removes files needed for grunt if it isn't going to be used
|
||||
"""
|
||||
for filename in ["Gruntfile.js"]:
|
||||
os.remove(os.path.join(
|
||||
PROJECT_DIRECTORY, filename
|
||||
))
|
||||
file_names = [
|
||||
'Gruntfile.js',
|
||||
]
|
||||
for file_name in file_names:
|
||||
os.remove(os.path.join(PROJECT_DIR_PATH, file_name))
|
||||
|
||||
|
||||
def remove_gulp_files():
|
||||
file_names = [
|
||||
'gulpfile.js',
|
||||
]
|
||||
for file_name in file_names:
|
||||
os.remove(os.path.join(PROJECT_DIR_PATH, file_name))
|
||||
|
||||
|
||||
def remove_packagejson_file():
|
||||
file_names = [
|
||||
'package.json',
|
||||
]
|
||||
for file_name in file_names:
|
||||
os.remove(os.path.join(PROJECT_DIR_PATH, file_name))
|
||||
|
||||
|
||||
def remove_celery_app():
|
||||
shutil.rmtree(os.path.join(PROJECT_DIR_PATH, '{{ cookiecutter.project_slug }}', 'taskapp'))
|
||||
|
||||
|
||||
def append_to_project_gitignore(path):
|
||||
gitignore_file_path = os.path.join(PROJECT_DIR_PATH, '.gitignore')
|
||||
with open(gitignore_file_path, 'a') as gitignore_file:
|
||||
gitignore_file.write(path)
|
||||
gitignore_file.write(os.linesep)
|
||||
|
||||
|
||||
def generate_random_string(length,
|
||||
using_digits=False,
|
||||
using_ascii_letters=False,
|
||||
using_punctuation=False):
|
||||
"""
|
||||
Removes files needed for grunt if it isn't going to be used
|
||||
Example:
|
||||
opting out for 50 symbol-long, [a-z][A-Z][0-9] string
|
||||
would yield log_2((26+26+50)^50) ~= 334 bit strength.
|
||||
"""
|
||||
for filename in ["gulpfile.js"]:
|
||||
os.remove(os.path.join(
|
||||
PROJECT_DIRECTORY, filename
|
||||
))
|
||||
if not using_sysrandom:
|
||||
return None
|
||||
|
||||
def remove_packageJSON_file():
|
||||
"""
|
||||
Removes files needed for grunt if it isn't going to be used
|
||||
"""
|
||||
for filename in ["package.json"]:
|
||||
os.remove(os.path.join(
|
||||
PROJECT_DIRECTORY, filename
|
||||
))
|
||||
symbols = []
|
||||
if using_digits:
|
||||
symbols += string.digits
|
||||
if using_ascii_letters:
|
||||
symbols += string.ascii_letters
|
||||
if using_punctuation:
|
||||
symbols += string.punctuation \
|
||||
.replace('"', '') \
|
||||
.replace("'", '') \
|
||||
.replace('\\', '')
|
||||
return ''.join([random.choice(symbols) for _ in range(length)])
|
||||
|
||||
|
||||
def remove_copying_files():
|
||||
"""
|
||||
Removes files needed for the GPLv3 licence if it isn't going to be used
|
||||
"""
|
||||
for filename in ["COPYING"]:
|
||||
os.remove(os.path.join(
|
||||
PROJECT_DIRECTORY, filename
|
||||
))
|
||||
def set_flag(file_path,
|
||||
flag,
|
||||
value=None,
|
||||
*args,
|
||||
**kwargs):
|
||||
if value is None:
|
||||
random_string = generate_random_string(*args, **kwargs)
|
||||
if random_string is None:
|
||||
import sys
|
||||
sys.stdout.write(
|
||||
"We couldn't find a secure pseudo-random number generator on your system. "
|
||||
"Please, make sure to manually {} later.".format(flag)
|
||||
)
|
||||
random_string = flag
|
||||
value = random_string
|
||||
|
||||
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)
|
||||
with open(file_path, 'r+') as f:
|
||||
file_contents = f.read().replace(flag, value)
|
||||
f.seek(0)
|
||||
f.write(file_contents)
|
||||
f.truncate()
|
||||
|
||||
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
|
||||
))
|
||||
|
||||
def remove_open_source_files():
|
||||
"""
|
||||
Removes files conventional to opensource projects only.
|
||||
"""
|
||||
for filename in ["CONTRIBUTORS.txt"]:
|
||||
os.remove(os.path.join(
|
||||
PROJECT_DIRECTORY, filename
|
||||
))
|
||||
return value
|
||||
|
||||
|
||||
# IN PROGRESS
|
||||
# def copy_doc_files(project_directory):
|
||||
# cookiecutters_dir = DEFAULT_CONFIG['cookiecutters_dir']
|
||||
# cookiecutter_django_dir = os.path.join(
|
||||
# cookiecutters_dir,
|
||||
# 'cookiecutter-django',
|
||||
# 'docs'
|
||||
# )
|
||||
# target_dir = os.path.join(
|
||||
# project_directory,
|
||||
# 'docs'
|
||||
# )
|
||||
# for name in os.listdir(cookiecutter_django_dir):
|
||||
# if name.endswith('.rst') and not name.startswith('index'):
|
||||
# src = os.path.join(cookiecutter_django_dir, name)
|
||||
# dst = os.path.join(target_dir, name)
|
||||
# shutil.copyfile(src, dst)
|
||||
def set_django_secret_key(file_path):
|
||||
django_secret_key = set_flag(
|
||||
file_path,
|
||||
'!!!SET DJANGO_SECRET_KEY!!!',
|
||||
length=50,
|
||||
using_digits=True,
|
||||
using_ascii_letters=True
|
||||
)
|
||||
return django_secret_key
|
||||
|
||||
# Generates and saves random secret key
|
||||
make_secret_key(PROJECT_DIRECTORY)
|
||||
|
||||
# Removes the taskapp if celery isn't going to be used
|
||||
if '{{ cookiecutter.use_celery }}'.lower() == 'n':
|
||||
remove_task_app(PROJECT_DIRECTORY)
|
||||
def set_postgres_user(file_path,
|
||||
value=None):
|
||||
postgres_user = set_flag(
|
||||
file_path,
|
||||
'!!!SET POSTGRES_USER!!!',
|
||||
value=value,
|
||||
length=8,
|
||||
using_ascii_letters=True
|
||||
)
|
||||
return postgres_user
|
||||
|
||||
# Removes the .idea directory if PyCharm isn't going to be used
|
||||
if '{{ cookiecutter.use_pycharm }}'.lower() != 'y':
|
||||
remove_pycharm_dir(PROJECT_DIRECTORY)
|
||||
|
||||
# Removes all heroku files if it isn't going to be used
|
||||
if '{{ cookiecutter.use_heroku }}'.lower() != 'y':
|
||||
remove_heroku_files()
|
||||
def set_postgres_password(file_path):
|
||||
postgres_password = set_flag(
|
||||
file_path,
|
||||
'!!!SET POSTGRES_PASSWORD!!!',
|
||||
length=42,
|
||||
using_digits=True,
|
||||
using_ascii_letters=True
|
||||
)
|
||||
return postgres_password
|
||||
|
||||
# Removes all docker files if it isn't going to be used
|
||||
if '{{ cookiecutter.use_docker }}'.lower() != 'y':
|
||||
|
||||
def initialize_dotenv(postgres_user):
|
||||
# Initializing `env.example` first.
|
||||
envexample_file_path = os.path.join(PROJECT_DIR_PATH, 'env.example')
|
||||
set_django_secret_key(envexample_file_path)
|
||||
set_postgres_user(envexample_file_path, value=postgres_user)
|
||||
set_postgres_password(envexample_file_path)
|
||||
# Renaming `env.example` to `.env`.
|
||||
dotenv_file_path = os.path.join(PROJECT_DIR_PATH, '.env')
|
||||
shutil.move(envexample_file_path, dotenv_file_path)
|
||||
|
||||
|
||||
def initialize_localyml(postgres_user):
|
||||
set_postgres_user(os.path.join(PROJECT_DIR_PATH, 'local.yml'), value=postgres_user)
|
||||
|
||||
|
||||
def initialize_local_settings():
|
||||
set_django_secret_key(os.path.join(PROJECT_DIR_PATH, 'config', 'settings', 'local.py'))
|
||||
|
||||
|
||||
def initialize_test_settings():
|
||||
set_django_secret_key(os.path.join(PROJECT_DIR_PATH, 'config', 'settings', 'test.py'))
|
||||
|
||||
|
||||
def main():
|
||||
postgres_user = generate_random_string(length=16, using_ascii_letters=True)
|
||||
initialize_dotenv(postgres_user)
|
||||
initialize_localyml(postgres_user)
|
||||
initialize_local_settings()
|
||||
initialize_test_settings()
|
||||
|
||||
if '{{ cookiecutter.open_source_license }}' == 'Not open source':
|
||||
remove_open_source_project_only_files()
|
||||
elif '{{ cookiecutter.open_source_license}}' != 'GPLv3':
|
||||
remove_gplv3_files()
|
||||
|
||||
if '{{ cookiecutter.use_pycharm }}'.lower() == 'n':
|
||||
remove_pycharm_files()
|
||||
|
||||
if '{{ cookiecutter.use_docker }}'.lower() == 'n':
|
||||
remove_docker_files()
|
||||
|
||||
# Removes all JS task manager files if it isn't going to be used
|
||||
if '{{ cookiecutter.js_task_runner}}'.lower() == 'gulp':
|
||||
remove_grunt_files()
|
||||
elif '{{ cookiecutter.js_task_runner}}'.lower() == 'grunt':
|
||||
remove_gulp_files()
|
||||
else:
|
||||
remove_gulp_files()
|
||||
remove_grunt_files()
|
||||
remove_packageJSON_file()
|
||||
remove_paas_files()
|
||||
|
||||
# Display a warning if use_docker and use_grunt are selected. Grunt isn't
|
||||
# supported by our docker config atm.
|
||||
if '{{ cookiecutter.js_task_runner }}'.lower() in ['grunt', 'gulp'] and '{{ cookiecutter.use_docker }}'.lower() == 'y':
|
||||
print(
|
||||
"You selected to use docker and a JS task runner. This is NOT supported out of the box for now. You "
|
||||
"can continue to use the project like you normally would, but you will need to add a "
|
||||
"js task runner service to your docker configuration manually."
|
||||
if '{{ cookiecutter.js_task_runner}}'.lower() == 'gulp':
|
||||
remove_grunt_files()
|
||||
elif '{{ cookiecutter.js_task_runner}}'.lower() == 'grunt':
|
||||
remove_gulp_files()
|
||||
else:
|
||||
remove_gulp_files()
|
||||
remove_grunt_files()
|
||||
remove_packagejson_file()
|
||||
|
||||
if '{{ cookiecutter.js_task_runner }}'.lower() in ['grunt', 'gulp'] \
|
||||
and '{{ cookiecutter.use_docker }}'.lower() == 'y':
|
||||
TERMINATOR = "\x1b[0m"
|
||||
INFO = "\x1b[1;33m [INFO]: "
|
||||
sys.stdout.write(
|
||||
INFO +
|
||||
"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_celery }}'.lower() == 'n':
|
||||
remove_celery_app()
|
||||
|
||||
# Removes files needed for the GPLv3 licence if it isn't going to be used.
|
||||
if '{{ cookiecutter.open_source_license}}' != 'GPLv3':
|
||||
remove_copying_files()
|
||||
|
||||
# Remove Elastic Beanstalk files
|
||||
if '{{ cookiecutter.use_elasticbeanstalk_experimental }}'.lower() != 'y':
|
||||
remove_elasticbeanstalk()
|
||||
|
||||
# Remove files conventional to opensource projects only.
|
||||
if '{{ cookiecutter.open_source_license }}' == 'Not open source':
|
||||
remove_open_source_files()
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,31 +1,59 @@
|
|||
"""
|
||||
NOTE:
|
||||
the below code is to be maintained Python 2.x-compatible
|
||||
as the whole Cookiecutter Django project initialization
|
||||
can potentially be run in Python 2.x environment.
|
||||
|
||||
TODO: ? restrict Cookiecutter Django project initialization to Python 3.x environments only
|
||||
"""
|
||||
|
||||
project_slug = '{{ cookiecutter.project_slug }}'
|
||||
|
||||
if hasattr(project_slug, 'isidentifier'):
|
||||
assert project_slug.isidentifier(), 'Project slug should be valid Python identifier!'
|
||||
assert project_slug.isidentifier(), "'{}' project slug is not a valid Python identifier.".format(project_slug)
|
||||
|
||||
elasticbeanstalk = '{{ cookiecutter.use_elasticbeanstalk_experimental }}'.lower()
|
||||
heroku = '{{ cookiecutter.use_heroku }}'.lower()
|
||||
docker = '{{ cookiecutter.use_docker }}'.lower()
|
||||
using_docker = '{{ cookiecutter.use_docker }}'.lower()
|
||||
if using_docker == 'n':
|
||||
TERMINATOR = "\x1b[0m"
|
||||
WARNING = "\x1b[1;33m [WARNING]: "
|
||||
INFO = "\x1b[1;33m [INFO]: "
|
||||
HINT = "\x1b[3;33m"
|
||||
SUCCESS = "\x1b[1;32m [SUCCESS]: "
|
||||
|
||||
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.")
|
||||
|
||||
if docker == 'n':
|
||||
import sys
|
||||
|
||||
python_major_version = sys.version_info[0]
|
||||
|
||||
if python_major_version == 2:
|
||||
sys.stdout.write("WARNING: Cookiecutter Django does not support Python 2! Stability is guaranteed with Python 3.4+ only. Are you sure you want to proceed? (y/n)")
|
||||
|
||||
yes_options = set(['y'])
|
||||
no_options = set(['n', ''])
|
||||
sys.stdout.write(
|
||||
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
|
||||
)
|
||||
yes_options, no_options = frozenset(['y']), frozenset(['n'])
|
||||
while True:
|
||||
choice = raw_input().lower()
|
||||
if choice in no_options:
|
||||
if choice in yes_options:
|
||||
break
|
||||
elif choice in no_options:
|
||||
sys.stdout.write(
|
||||
INFO +
|
||||
"Generation process stopped as requested." +
|
||||
TERMINATOR
|
||||
)
|
||||
sys.exit(1)
|
||||
elif choice in yes_options:
|
||||
pass
|
||||
else:
|
||||
sys.stdout.write("Please respond with %s or %s"
|
||||
% (', '.join([o for o in yes_options if not o == ''])
|
||||
, ', '.join([o for o in no_options if not o == ''])))
|
||||
sys.stdout.write(
|
||||
HINT +
|
||||
"Please respond with {} or {}: ".format(
|
||||
', '.join(["'{}'".format(o) for o in yes_options if not o == '']),
|
||||
', '.join(["'{}'".format(o) for o in no_options if not o == ''])
|
||||
) +
|
||||
TERMINATOR
|
||||
)
|
||||
|
||||
sys.stdout.write(
|
||||
SUCCESS +
|
||||
"Project initialized, keep up the good work!" +
|
||||
TERMINATOR
|
||||
)
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
# These requirements prevented an upgrade to Django 1.10.
|
||||
django-coverage-plugin==1.5.0
|
||||
# These requirements prevented an upgrade to Django 1.11.
|
||||
django-autoslug==1.9.3
|
||||
|
||||
|
|
7
setup.py
7
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.11.8'
|
||||
version = '1.11.9'
|
||||
|
||||
if sys.argv[-1] == 'tag':
|
||||
os.system('git tag -a %s -m "version %s"' % (version, version))
|
||||
|
@ -34,14 +34,13 @@ setup(
|
|||
classifiers=[
|
||||
'Development Status :: 4 - Beta',
|
||||
'Environment :: Console',
|
||||
'Framework :: Django :: 1.10',
|
||||
'Framework :: Django :: 1.11',
|
||||
'Intended Audience :: Developers',
|
||||
'Natural Language :: English',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: PyPy',
|
||||
'Topic :: Software Development',
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
packages:
|
||||
yum:
|
||||
git: []
|
||||
postgresql94-devel: []
|
||||
libjpeg-turbo-devel: []
|
||||
libffi: []
|
||||
libffi-devel: []
|
|
@ -1,46 +0,0 @@
|
|||
#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.t2.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"
|
|
@ -1,6 +0,0 @@
|
|||
option_settings:
|
||||
"aws:elasticbeanstalk:customoption":
|
||||
CacheNodeType : cache.t2.micro
|
||||
NumCacheNodes : 1
|
||||
Engine : redis
|
||||
CachePort : 6379
|
|
@ -1,17 +0,0 @@
|
|||
container_commands:
|
||||
01_migrate:
|
||||
command: "source /opt/python/run/venv/bin/activate && python manage.py migrate --noinput"
|
||||
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/"
|
|
@ -1,3 +0,0 @@
|
|||
container_commands:
|
||||
01_setup_apache:
|
||||
command: "cp .ebextensions/enable_mod_deflate.conf /etc/httpd/conf.d/enable_mod_deflate.conf"
|
|
@ -1,25 +0,0 @@
|
|||
# mod_deflate configuration
|
||||
<IfModule mod_deflate.c>
|
||||
# Restrict compression to these MIME types
|
||||
AddOutputFilterByType DEFLATE text/plain
|
||||
AddOutputFilterByType DEFLATE text/html
|
||||
AddOutputFilterByType DEFLATE application/xhtml+xml
|
||||
AddOutputFilterByType DEFLATE text/xml
|
||||
AddOutputFilterByType DEFLATE application/xml
|
||||
AddOutputFilterByType DEFLATE application/xml+rss
|
||||
AddOutputFilterByType DEFLATE application/x-javascript
|
||||
AddOutputFilterByType DEFLATE text/javascript
|
||||
AddOutputFilterByType DEFLATE text/css
|
||||
# Level of compression (Highest 9 - Lowest 1)
|
||||
DeflateCompressionLevel 9
|
||||
# Netscape 4.x has some problems.
|
||||
BrowserMatch ^Mozilla/4 gzip-only-text/html
|
||||
# Netscape 4.06-4.08 have some more problems
|
||||
BrowserMatch ^Mozilla/4\.0[678] no-gzip
|
||||
# MSIE masquerades as Netscape, but it is fine
|
||||
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
|
||||
<IfModule mod_headers.c>
|
||||
# Make sure proxies don't deliver the wrong content
|
||||
Header append Vary User-Agent env=!dont-vary
|
||||
</IfModule>
|
||||
</IfModule>
|
|
@ -8,4 +8,4 @@ before_install:
|
|||
- sudo apt-get install -qq libsqlite3-dev libxml2 libxml2-dev libssl-dev libbz2-dev wget curl llvm
|
||||
language: python
|
||||
python:
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
|
|
|
@ -61,7 +61,7 @@ module.exports = function (grunt) {
|
|||
options: {
|
||||
outputStyle: 'nested',
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
includePaths: ['bower_components/bootstrap-sass/assets/stylesheets/bootstrap/'],
|
||||
includePaths: ['node_modules/bootstrap/scss'],
|
||||
{% endif %}
|
||||
sourceMap: false,
|
||||
precision: 10
|
||||
|
@ -74,7 +74,7 @@ module.exports = function (grunt) {
|
|||
options: {
|
||||
outputStyle: 'compressed',
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
includePaths: ['bower_components/bootstrap-sass/assets/stylesheets/bootstrap/'],
|
||||
includePaths: ['node_modules/bootstrap/scss'],
|
||||
{% endif %}
|
||||
sourceMap: false,
|
||||
precision: 10
|
||||
|
|
|
@ -132,22 +132,21 @@ 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.lower() == 'y' %}
|
||||
|
||||
Elastic Beanstalk
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
See detailed `cookiecutter-django Elastic Beanstalk documentation`_.
|
||||
|
||||
.. _`cookiecutter-django Elastic Beanstalk documentation`: http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-elastic-beanstalk.html
|
||||
|
||||
{% endif %}
|
||||
{% if cookiecutter.custom_bootstrap_compilation == "y" %}
|
||||
Custom Bootstrap Compilation
|
||||
^^^^^^
|
||||
|
||||
To get automatic Bootstrap recompilation with variables of your choice, install bootstrap sass (`bower install bootstrap-sass`) and tweak your variables in `static/sass/custom_bootstrap_vars`.
|
||||
The generated CSS is set up with automatic Bootstrap recompilation with variables of your choice.
|
||||
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-sass source](https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/_variables.scss), or get explanations on them in the [Bootstrap docs](https://getbootstrap.com/customize/).)
|
||||
You can find a list of available variables `in the bootstrap source`_, or get explanations on them in the `Bootstrap docs`_.
|
||||
|
||||
{% if cookiecutter.js_task_runner == 'Gulp' %}
|
||||
Bootstrap's javascript as well as its dependencies is concatenated into a single file: ``static/js/vendors.js``.
|
||||
{% endif %}
|
||||
|
||||
.. _in the bootstrap source: https://github.com/twbs/bootstrap/blob/v4-dev/scss/_variables.scss
|
||||
.. _Bootstrap docs: https://getbootstrap.com/docs/4.0/getting-started/theming/
|
||||
|
||||
{% endif %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM python:3.5
|
||||
FROM python:3.6
|
||||
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM python:3.5
|
||||
FROM python:3.6
|
||||
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ TEMPLATES[0]['OPTIONS']['debug'] = DEBUG
|
|||
# ------------------------------------------------------------------------------
|
||||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
|
||||
# Note: This key only used for development and testing.
|
||||
SECRET_KEY = env('DJANGO_SECRET_KEY', default='CHANGEME!!!')
|
||||
SECRET_KEY = env('DJANGO_SECRET_KEY', default='!!!SET DJANGO_SECRET_KEY!!!')
|
||||
|
||||
# Mail settings
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -172,36 +172,17 @@ TEMPLATES[0]['OPTIONS']['loaders'] = [
|
|||
{% set _DEFAULT_CONN_MAX_AGE=60 %}
|
||||
# DATABASE CONFIGURATION
|
||||
# ------------------------------------------------------------------------------
|
||||
{% if cookiecutter.use_elasticbeanstalk_experimental.lower() == 'y' -%}
|
||||
# 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'),
|
||||
'CONN_MAX_AGE': env.int('CONN_MAX_AGE', default={{ _DEFAULT_CONN_MAX_AGE }}),
|
||||
}
|
||||
}
|
||||
{% else %}
|
||||
|
||||
# Use the Heroku-style specification
|
||||
# Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ
|
||||
DATABASES['default'] = env.db('DATABASE_URL')
|
||||
DATABASES['default']['CONN_MAX_AGE'] = env.int('CONN_MAX_AGE', default={{ _DEFAULT_CONN_MAX_AGE }})
|
||||
{%- endif %}
|
||||
|
||||
|
||||
# CACHING
|
||||
# ------------------------------------------------------------------------------
|
||||
{% if cookiecutter.use_elasticbeanstalk_experimental.lower() == 'y' -%}
|
||||
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': {
|
||||
|
|
|
@ -17,7 +17,7 @@ TEMPLATES[0]['OPTIONS']['debug'] = False
|
|||
# ------------------------------------------------------------------------------
|
||||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
|
||||
# Note: This key only used for development and testing.
|
||||
SECRET_KEY = env('DJANGO_SECRET_KEY', default='CHANGEME!!!')
|
||||
SECRET_KEY = env('DJANGO_SECRET_KEY', default='!!!SET DJANGO_SECRET_KEY!!!')
|
||||
|
||||
# Mail settings
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -20,7 +20,8 @@ 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.dirname(os.path.abspath(__file__)).replace('/config', '')
|
||||
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_for_error_reporting == 'y' -%}
|
||||
|
|
|
@ -58,7 +58,7 @@ The `Docker compose documentation`_ explains in detail what you can accomplish i
|
|||
build: database
|
||||
webapp:
|
||||
build: webapp:
|
||||
command: /usr/bin/python3.4 manage.py runserver 0.0.0.0:8000 # dev setting
|
||||
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/
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
"""Converts a .env file to Elastic Beanstalk environment variables"""
|
||||
|
||||
import os
|
||||
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():
|
||||
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))
|
||||
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()
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
# PostgreSQL
|
||||
POSTGRES_PASSWORD=mysecretpass
|
||||
POSTGRES_USER=postgresuser
|
||||
POSTGRES_PASSWORD=!!!SET POSTGRES_PASSWORD!!!
|
||||
POSTGRES_USER=!!!SET POSTGRES_USER!!!
|
||||
CONN_MAX_AGE=
|
||||
|
||||
# Domain name, used by caddy
|
||||
|
@ -11,7 +11,7 @@ DOMAIN_NAME={{ cookiecutter.domain_name }}
|
|||
# DJANGO_READ_DOT_ENV_FILE=True
|
||||
DJANGO_ADMIN_URL=
|
||||
DJANGO_SETTINGS_MODULE=config.settings.production
|
||||
DJANGO_SECRET_KEY=CHANGEME!!!
|
||||
DJANGO_SECRET_KEY=!!!SET DJANGO_SECRET_KEY!!!
|
||||
DJANGO_ALLOWED_HOSTS=.{{ cookiecutter.domain_name }}
|
||||
|
||||
# AWS Settings
|
||||
|
|
|
@ -10,6 +10,9 @@ var gulp = require('gulp'),
|
|||
sass = require('gulp-sass'),
|
||||
autoprefixer = require('gulp-autoprefixer'),
|
||||
cssnano = require('gulp-cssnano'),
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
concat = require('gulp-concat'),
|
||||
{% endif %}
|
||||
rename = require('gulp-rename'),
|
||||
del = require('del'),
|
||||
plumber = require('gulp-plumber'),
|
||||
|
@ -25,15 +28,24 @@ var gulp = require('gulp'),
|
|||
// Relative paths function
|
||||
var pathsConfig = function (appName) {
|
||||
this.app = "./" + (appName || pjson.name);
|
||||
var vendorsRoot = 'node_modules/';
|
||||
|
||||
return {
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
bootstrapSass: vendorsRoot + '/bootstrap/scss',
|
||||
vendorsJs: [
|
||||
vendorsRoot + 'jquery/dist/jquery.slim.js',
|
||||
vendorsRoot + 'popper.js/dist/umd/popper.js',
|
||||
vendorsRoot + 'bootstrap/dist/js/bootstrap.js'
|
||||
],
|
||||
{% endif %}
|
||||
app: this.app,
|
||||
templates: this.app + '/templates',
|
||||
css: this.app + '/static/css',
|
||||
sass: this.app + '/static/sass',
|
||||
fonts: this.app + '/static/fonts',
|
||||
images: this.app + '/static/images',
|
||||
js: this.app + '/static/js',
|
||||
js: this.app + '/static/js'
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -45,8 +57,15 @@ var paths = pathsConfig();
|
|||
|
||||
// Styles autoprefixing and minification
|
||||
gulp.task('styles', function() {
|
||||
return gulp.src(paths.sass + '/*.scss')
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
return gulp.src(paths.sass + '/project.scss')
|
||||
.pipe(sass({
|
||||
includePaths: [
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
paths.bootstrapSass,
|
||||
{% endif %}
|
||||
paths.sass
|
||||
]
|
||||
}).on('error', sass.logError))
|
||||
.pipe(plumber()) // Checks for errors
|
||||
.pipe(autoprefixer({browsers: ['last 2 versions']})) // Adds vendor prefixes
|
||||
.pipe(pixrem()) // add fallbacks for rem units
|
||||
|
@ -65,6 +84,20 @@ gulp.task('scripts', function() {
|
|||
.pipe(gulp.dest(paths.js));
|
||||
});
|
||||
|
||||
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
// Vendor Javascript minification
|
||||
gulp.task('vendor-scripts', function() {
|
||||
return gulp.src(paths.vendorsJs)
|
||||
.pipe(concat('vendors.js'))
|
||||
.pipe(gulp.dest(paths.js))
|
||||
.pipe(plumber()) // Checks for errors
|
||||
.pipe(uglify()) // Minifies the js
|
||||
.pipe(rename({ suffix: '.min' }))
|
||||
.pipe(gulp.dest(paths.js));
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
// Image compression
|
||||
gulp.task('imgCompression', function(){
|
||||
return gulp.src(paths.images + '/*')
|
||||
|
@ -101,5 +134,5 @@ gulp.task('watch', function() {
|
|||
|
||||
// Default task
|
||||
gulp.task('default', function() {
|
||||
runSequence(['styles', 'scripts', 'imgCompression'], ['runServer', 'browserSync', 'watch']);
|
||||
runSequence(['styles', 'scripts', {% if cookiecutter.custom_bootstrap_compilation == 'y' %}'vendor-scripts', {% endif %}'imgCompression'], ['runServer', 'browserSync', 'watch']);
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ services:
|
|||
volumes:
|
||||
- .:/app
|
||||
environment:
|
||||
- POSTGRES_USER={{cookiecutter.project_slug}}
|
||||
- POSTGRES_USER=!!!SET POSTGRES_USER!!!
|
||||
- USE_DOCKER=yes
|
||||
ports:
|
||||
- "8000:8000"
|
||||
|
@ -29,7 +29,7 @@ services:
|
|||
- postgres_data_local:/var/lib/postgresql/data
|
||||
- postgres_backup_local:/backups
|
||||
environment:
|
||||
- POSTGRES_USER={{cookiecutter.project_slug}}
|
||||
- POSTGRES_USER=!!!SET POSTGRES_USER!!!
|
||||
{% if cookiecutter.use_mailhog == 'y' %}
|
||||
mailhog:
|
||||
image: mailhog/mailhog:v1.0.0
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
"devDependencies": {
|
||||
{% if cookiecutter.js_task_runner == 'Grunt' %}
|
||||
"autoprefixer-core": "~5.2.1",
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
"bootstrap": "^4.0.0",
|
||||
{% endif %}
|
||||
"connect-livereload": "~0.3.2",
|
||||
"cssnano": "~2.1.0",
|
||||
"grunt": "~0.4.5",
|
||||
|
@ -12,14 +15,26 @@
|
|||
"grunt-contrib-watch": "~0.6.1",
|
||||
"grunt-postcss": "~0.5.5",
|
||||
"grunt-sass": "~1.0.0",
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
"jquery": "^3.2.1-slim",
|
||||
{% endif %}
|
||||
"load-grunt-tasks": "~3.2.0",
|
||||
"pixrem": "~1.3.1",
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
"popper.js": "^1.12.3",
|
||||
{% endif %}
|
||||
"time-grunt": "~1.2.1"
|
||||
{% elif cookiecutter.js_task_runner == 'Gulp' %}
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
"bootstrap": "^4.0.0",
|
||||
{% endif %}
|
||||
"browser-sync": "^2.14.0",
|
||||
"del": "^2.2.2",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "^3.1.1",
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
"gulp-concat": "^2.6.1",
|
||||
{% endif %}
|
||||
"gulp-cssnano": "^2.1.2",
|
||||
"gulp-imagemin": "^3.0.3",
|
||||
"gulp-pixrem": "^1.0.0",
|
||||
|
@ -28,6 +43,10 @@
|
|||
"gulp-sass": "^2.3.2",
|
||||
"gulp-uglify": "^2.0.0",
|
||||
"gulp-util": "^3.0.7",
|
||||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
"jquery": "^3.2.1-slim",
|
||||
"popper.js": "^1.12.3",
|
||||
{% endif %}
|
||||
"run-sequence": "^1.2.2"
|
||||
{% endif %}
|
||||
},
|
||||
|
|
|
@ -6,7 +6,7 @@ wheel==0.30.0
|
|||
|
||||
|
||||
# Conservative Django
|
||||
django==1.11.9 # pyup: <2.0
|
||||
django==1.11.10 # pyup: <2.0
|
||||
|
||||
# Configuration
|
||||
django-environ==0.4.4
|
||||
|
@ -29,14 +29,14 @@ argon2-cffi==18.1.0
|
|||
|
||||
# For user registration, either via email or social
|
||||
# Well-built with regular release cycles!
|
||||
django-allauth==0.34.0
|
||||
django-allauth==0.35.0
|
||||
|
||||
{% 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.7.3.2
|
||||
psycopg2==2.7.4
|
||||
{%- endif %}
|
||||
|
||||
# Unicode slugification
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# Local development dependencies go here
|
||||
-r base.txt
|
||||
|
||||
coverage==4.4.2
|
||||
coverage==4.5
|
||||
django-coverage-plugin==1.5.0
|
||||
|
||||
Sphinx==1.6.6
|
||||
django-extensions==1.9.8
|
||||
Sphinx==1.6.7
|
||||
django-extensions==1.9.9
|
||||
Werkzeug==0.14.1
|
||||
django-test-plus==1.0.22
|
||||
factory-boy==2.9.2
|
||||
factory-boy==2.10.0
|
||||
|
||||
django-debug-toolbar==1.9.1
|
||||
|
||||
|
@ -16,4 +16,4 @@ django-debug-toolbar==1.9.1
|
|||
ipdb==0.10.3
|
||||
|
||||
pytest-django==3.1.2
|
||||
pytest-sugar==0.9.0
|
||||
pytest-sugar==0.9.1
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# Python-PostgreSQL Database Adapter
|
||||
# Assuming Windows is used locally, and *nix -- in production.
|
||||
# ------------------------------------------------------------
|
||||
psycopg2==2.7.3.2
|
||||
psycopg2==2.7.4
|
||||
{%- endif %}
|
||||
|
||||
# WSGI Handler
|
||||
|
@ -16,7 +16,7 @@ gunicorn==19.7.1
|
|||
|
||||
# Static and Media Storage
|
||||
# ------------------------------------------------
|
||||
boto3==1.5.12
|
||||
boto3==1.5.25
|
||||
django-storages==1.6.5
|
||||
{% if cookiecutter.use_whitenoise != 'y' -%}
|
||||
Collectfast==0.6.0
|
||||
|
@ -24,16 +24,16 @@ Collectfast==0.6.0
|
|||
|
||||
# Email backends for Mailgun, Postmark, SendGrid and more
|
||||
# -------------------------------------------------------
|
||||
django-anymail==1.2
|
||||
django-anymail==1.4
|
||||
|
||||
{% if cookiecutter.use_sentry_for_error_reporting == "y" -%}
|
||||
# Raven is the Sentry client
|
||||
# --------------------------
|
||||
raven==6.4.0
|
||||
raven==6.5.0
|
||||
{%- endif %}
|
||||
|
||||
{% if cookiecutter.use_opbeat == "y" -%}
|
||||
# Opbeat agent for performance monitoring
|
||||
# -----------------------------------------
|
||||
opbeat==3.6.0
|
||||
opbeat==3.6.1
|
||||
{%- endif %}
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
{% if cookiecutter.windows == 'y' -%}
|
||||
# Python-PostgreSQL Database Adapter
|
||||
# If using Win for dev, this assumes Unix in test/prod
|
||||
psycopg2==2.7.3.2
|
||||
psycopg2==2.7.4
|
||||
{%- endif %}
|
||||
|
||||
coverage==4.4.2
|
||||
coverage==4.5
|
||||
flake8==3.5.0 # pyup: != 2.6.0
|
||||
django-test-plus==1.0.22
|
||||
factory-boy==2.9.2
|
||||
factory-boy==2.10.0
|
||||
django-coverage-plugin==1.5.0
|
||||
|
||||
# pytest
|
||||
pytest-django==3.1.2
|
||||
pytest-sugar==0.9.0
|
||||
pytest-sugar==0.9.1
|
||||
|
|
|
@ -1 +1 @@
|
|||
python-3.6.2
|
||||
python-3.6.4
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
##basic build dependencies of various Django apps for Debian Jessie 9.x
|
||||
#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
|
||||
libjpeg62-turbo-dev
|
||||
libfreetype6-dev
|
||||
liblcms2-dev
|
||||
libwebp-dev
|
||||
|
||||
##django-extensions
|
||||
graphviz-dev
|
|
@ -11,11 +11,3 @@
|
|||
background-color: #f2dede;
|
||||
border-color: #eed3d7;
|
||||
}
|
||||
|
||||
/* Display django-debug-toolbar.
|
||||
See https://github.com/django-debug-toolbar/django-debug-toolbar/issues/742
|
||||
and https://github.com/pydanny/cookiecutter-django/issues/317
|
||||
*/
|
||||
[hidden][style="display: block;"] {
|
||||
display: block !important;
|
||||
}
|
||||
|
|
|
@ -1,54 +1,6 @@
|
|||
{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
|
||||
@import "variables";
|
||||
@import "custom_bootstrap_vars";
|
||||
@import "mixins";
|
||||
|
||||
// Reset and dependencies
|
||||
@import "normalize";
|
||||
@import "print";
|
||||
@import "glyphicons";
|
||||
|
||||
// Core CSS
|
||||
@import "scaffolding";
|
||||
@import "type";
|
||||
@import "code";
|
||||
@import "grid";
|
||||
@import "tables";
|
||||
@import "forms";
|
||||
@import "buttons";
|
||||
|
||||
// Components
|
||||
@import "component-animations";
|
||||
@import "dropdowns";
|
||||
@import "button-groups";
|
||||
@import "input-groups";
|
||||
@import "navs";
|
||||
@import "navbar";
|
||||
@import "breadcrumbs";
|
||||
@import "pagination";
|
||||
@import "pager";
|
||||
@import "labels";
|
||||
@import "badges";
|
||||
@import "jumbotron";
|
||||
@import "thumbnails";
|
||||
@import "alerts";
|
||||
@import "progress-bars";
|
||||
@import "media";
|
||||
@import "list-group";
|
||||
@import "panels";
|
||||
@import "responsive-embed";
|
||||
@import "wells";
|
||||
@import "close";
|
||||
|
||||
// Components w/ JavaScript
|
||||
@import "modals";
|
||||
@import "tooltip";
|
||||
@import "popovers";
|
||||
@import "carousel";
|
||||
|
||||
// Utility classes
|
||||
@import "utilities";
|
||||
@import "responsive-utilities";
|
||||
@import "bootstrap";
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
@ -86,15 +38,3 @@ $red: #b94a48;
|
|||
border-color: $dark-pink;
|
||||
color: $red;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//Django Toolbar//
|
||||
////////////////////////////////
|
||||
|
||||
// Display django-debug-toolbar.
|
||||
// See https://github.com/django-debug-toolbar/django-debug-toolbar/issues/742
|
||||
// and https://github.com/pydanny/cookiecutter-django/issues/317
|
||||
|
||||
[hidden][style="display: block;"] {
|
||||
display: block !important;
|
||||
}
|
||||
|
|
|
@ -14,13 +14,19 @@
|
|||
<![endif]-->
|
||||
|
||||
{% block css %}
|
||||
{% endraw %}{% if cookiecutter.custom_bootstrap_compilation == "n" %}{% raw %}
|
||||
<!-- Latest compiled and minified Bootstrap 4 beta CSS -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
|
||||
{% endraw %}{% endif %}{% raw %}
|
||||
|
||||
<!-- Your stuff: Third-party CSS libraries go here -->
|
||||
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress css %}{% endraw %}{% endif %}{% raw %}
|
||||
<!-- This file stores project-specific CSS -->
|
||||
{% endraw %}{% if cookiecutter.js_task_runner == "Gulp" %}{% raw %}
|
||||
<link href="{% static 'css/project.min.css' %}" rel="stylesheet">
|
||||
{% endraw %}{% else %}{% raw %}
|
||||
<link href="{% static 'css/project.css' %}" rel="stylesheet">
|
||||
{% endraw %}{% endif %}{% raw %}
|
||||
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -88,12 +94,19 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
{% block javascript %}
|
||||
{% endraw %}{% if cookiecutter.custom_bootstrap_compilation == "y" and cookiecutter.js_task_runner == "Gulp" %}{% raw %}
|
||||
<!-- Vendor dependencies bundled as one file-->
|
||||
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
|
||||
<script src="{% static 'js/vendors.js' %}"></script>
|
||||
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
|
||||
{% endraw %}{% else %}{% raw %}
|
||||
<!-- Required by Bootstrap v4 beta -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- Your stuff: Third-party javascript libraries go here -->
|
||||
{% endraw %}{% endif %}{% raw %}
|
||||
|
||||
<!-- place project specific Javascript in this file -->
|
||||
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
{% raw %}
|
||||
{% load crispy_forms_field %}
|
||||
|
||||
{% if field.is_hidden %}
|
||||
{{ field }}
|
||||
{% else %}
|
||||
{% if field|is_checkbox %}
|
||||
<div class="form-group{% if using_grid_layout %} row{% endif %}">
|
||||
{% if label_class %}
|
||||
<div class="controls col-{{ bootstrap_device_type }}-offset-{{ label_size }} {{ field_class }}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" {% if not field|is_checkbox %}class="form-group{% if using_grid_layout %} row{% endif %}{% else %}class="checkbox{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_show_errors%}{% if field.errors %} has-danger{% endif %}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
|
||||
{% if field.label and not field|is_checkbox and form_show_labels %}
|
||||
<label for="{{ field.id_for_label }}" class="form-control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
|
||||
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
|
||||
</label>
|
||||
{% endif %}
|
||||
|
||||
{% if field|is_checkboxselectmultiple %}
|
||||
{% include 'bootstrap4/layout/checkboxselectmultiple.html' %}
|
||||
{% endif %}
|
||||
|
||||
{% if field|is_radioselect %}
|
||||
{% include 'bootstrap4/layout/radioselect.html' %}
|
||||
{% endif %}
|
||||
|
||||
{% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
|
||||
{% if field|is_checkbox and form_show_labels %}
|
||||
<label for="{{ field.id_for_label }}" class="{% if field.field.required %} requiredField{% endif %}">
|
||||
{% crispy_field field %}
|
||||
{{ field.label|safe }}
|
||||
{% include 'bootstrap4/layout/help_text_and_errors.html' %}
|
||||
</label>
|
||||
{% else %}
|
||||
<div class="{{ field_class }}">
|
||||
{% crispy_field field %}
|
||||
</div>
|
||||
{% include 'bootstrap4/layout/help_text_and_errors.html' %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</{% if tag %}{{ tag }}{% else %}div{% endif %}>
|
||||
{% if field|is_checkbox %}
|
||||
{% if label_class %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endraw %}
|
|
@ -1,7 +0,0 @@
|
|||
{% raw %}
|
||||
{% if form_show_errors and field.errors %}
|
||||
{% for error in field.errors %}
|
||||
<p id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="text-danger help-block">{{ error }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endraw %}
|
|
@ -1,6 +1,6 @@
|
|||
from django.contrib.auth.models import AbstractUser
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from django.core.urlresolvers import reverse, resolve
|
||||
from django.urls import reverse, resolve
|
||||
|
||||
from test_plus.test import TestCase
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from django.core.urlresolvers import reverse
|
||||
from django.views.generic import DetailView, ListView, RedirectView, UpdateView
|
||||
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.urls import reverse
|
||||
from django.views.generic import DetailView, ListView, RedirectView, UpdateView
|
||||
|
||||
from .models import User
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user