mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2025-04-25 10:53:45 +03:00
Merge branch 'master' into upgrade/django-2.2
This commit is contained in:
commit
15f283bb74
|
@ -2,6 +2,13 @@
|
||||||
All enhancements and patches to Cookiecutter Django will be documented in this file.
|
All enhancements and patches to Cookiecutter Django will be documented in this file.
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## [2019-05-18]
|
||||||
|
### Removed
|
||||||
|
- Remove the user list view (@browniebroke)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Static storage default ACL (@browniebroke)
|
||||||
|
|
||||||
## [2019-05-17]
|
## [2019-05-17]
|
||||||
### Fixed
|
### Fixed
|
||||||
- Added `LocaleMiddleware` to the list of middlewares (@tanoabeleyra)
|
- Added `LocaleMiddleware` to the list of middlewares (@tanoabeleyra)
|
||||||
|
|
|
@ -7,19 +7,19 @@ Core Developers
|
||||||
These contributors have commit flags for the repository,
|
These contributors have commit flags for the repository,
|
||||||
and are able to accept and merge pull requests.
|
and are able to accept and merge pull requests.
|
||||||
|
|
||||||
=========================== ================ ===========
|
=========================== ================= ===========
|
||||||
Name Github Twitter
|
Name Github Twitter
|
||||||
=========================== ================ ===========
|
=========================== ================= ===========
|
||||||
Daniel Roy Greenfeld `@pydanny`_ @pydanny
|
Daniel Roy Greenfeld `@pydanny`_ @pydanny
|
||||||
Audrey Roy Greenfeld* `@audreyr`_ @audreyr
|
Audrey Roy Greenfeld* `@audreyr`_ @audreyr
|
||||||
Fábio C. Barrionuevo da Luz `@luzfcb`_ @luzfcb
|
Fábio C. Barrionuevo da Luz `@luzfcb`_ @luzfcb
|
||||||
Saurabh Kumar `@theskumar`_ @_theskumar
|
Saurabh Kumar `@theskumar`_ @_theskumar
|
||||||
Jannis Gebauer `@jayfk`_
|
Jannis Gebauer `@jayfk`_
|
||||||
Burhan Khalid `@burhan`_ @burhan
|
Burhan Khalid `@burhan`_ @burhan
|
||||||
Nikita Shupeyko `@webyneter`_ @webyneter
|
Nikita Shupeyko `@webyneter`_ @webyneter
|
||||||
Bruno Alla `@browniebroke`_ @_BrunoAlla
|
Bruno Alla `@browniebroke`_ @_BrunoAlla
|
||||||
Wan Liuyang `@sfdye`_ @sfdye
|
Wan Liuyang `@sfdye`_ @sfdye
|
||||||
=========================== ================ ===========
|
=========================== ================= ===========
|
||||||
|
|
||||||
*Audrey is also the creator of Cookiecutter. Audrey and
|
*Audrey is also the creator of Cookiecutter. Audrey and
|
||||||
Daniel are on the Cookiecutter core team.*
|
Daniel are on the Cookiecutter core team.*
|
||||||
|
@ -87,6 +87,7 @@ Listed in alphabetical order.
|
||||||
Craig Margieson `@cmargieson`_
|
Craig Margieson `@cmargieson`_
|
||||||
Cristian Vargas `@cdvv7788`_
|
Cristian Vargas `@cdvv7788`_
|
||||||
Cullen Rhodes `@c-rhodes`_
|
Cullen Rhodes `@c-rhodes`_
|
||||||
|
Curtis St Pierre `@curtisstpierre`_ @cstpierre1388
|
||||||
Dan Shultz `@shultz`_
|
Dan Shultz `@shultz`_
|
||||||
Daniel Hepper `@dhepper`_ @danielhepper
|
Daniel Hepper `@dhepper`_ @danielhepper
|
||||||
Daniele Tricoli `@eriol`_
|
Daniele Tricoli `@eriol`_
|
||||||
|
@ -143,6 +144,7 @@ Listed in alphabetical order.
|
||||||
Mateusz Ostaszewski `@mostaszewski`_
|
Mateusz Ostaszewski `@mostaszewski`_
|
||||||
Mathijs Hoogland `@MathijsHoogland`_
|
Mathijs Hoogland `@MathijsHoogland`_
|
||||||
Matt Braymer-Hayes `@mattayes`_ @mattayes
|
Matt Braymer-Hayes `@mattayes`_ @mattayes
|
||||||
|
Matt Knapper `@mknapper1`_
|
||||||
Matt Linares
|
Matt Linares
|
||||||
Matt Menzenski `@menzenski`_
|
Matt Menzenski `@menzenski`_
|
||||||
Matt Warren `@mfwarren`_
|
Matt Warren `@mfwarren`_
|
||||||
|
@ -221,6 +223,7 @@ Listed in alphabetical order.
|
||||||
.. _@chuckus: https://github.com/chuckus
|
.. _@chuckus: https://github.com/chuckus
|
||||||
.. _@cmackenzie1: https://github.com/cmackenzie1
|
.. _@cmackenzie1: https://github.com/cmackenzie1
|
||||||
.. _@Collederas: https://github.com/Collederas
|
.. _@Collederas: https://github.com/Collederas
|
||||||
|
.. _@curtisstpierre: https://github.com/curtisstpierre
|
||||||
.. _@davitovmasyan: https://github.com/davitovmasyan
|
.. _@davitovmasyan: https://github.com/davitovmasyan
|
||||||
.. _@ddiazpinto: https://github.com/ddiazpinto
|
.. _@ddiazpinto: https://github.com/ddiazpinto
|
||||||
.. _@demestav: https://github.com/demestav
|
.. _@demestav: https://github.com/demestav
|
||||||
|
@ -260,6 +263,7 @@ Listed in alphabetical order.
|
||||||
.. _@msaizar: https://github.com/msaizar
|
.. _@msaizar: https://github.com/msaizar
|
||||||
.. _@MathijsHoogland: https://github.com/MathijsHoogland
|
.. _@MathijsHoogland: https://github.com/MathijsHoogland
|
||||||
.. _@mattayes: https://github.com/mattayes
|
.. _@mattayes: https://github.com/mattayes
|
||||||
|
.. _@mknapper1: https://github.com/mknapper1
|
||||||
.. _@menzenski: https://github.com/menzenski
|
.. _@menzenski: https://github.com/menzenski
|
||||||
.. _@mostaszewski: https://github.com/mostaszewski
|
.. _@mostaszewski: https://github.com/mostaszewski
|
||||||
.. _@mfwarren: https://github.com/mfwarren
|
.. _@mfwarren: https://github.com/mfwarren
|
||||||
|
|
20
README.rst
20
README.rst
|
@ -89,7 +89,7 @@ Constraints
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
* Only maintained 3rd party libraries are used.
|
* Only maintained 3rd party libraries are used.
|
||||||
* Uses PostgreSQL everywhere (9.4 - 10.5)
|
* Uses PostgreSQL everywhere (9.4 - 11.3)
|
||||||
* Environment variables for configuration (This won't work with Apache/mod_wsgi).
|
* Environment variables for configuration (This won't work with Apache/mod_wsgi).
|
||||||
|
|
||||||
Support this Project!
|
Support this Project!
|
||||||
|
@ -169,15 +169,12 @@ Answer the prompts with your own desired options_. For example::
|
||||||
use_heroku [n]: y
|
use_heroku [n]: y
|
||||||
use_compressor [n]: y
|
use_compressor [n]: y
|
||||||
Select postgresql_version:
|
Select postgresql_version:
|
||||||
1 - 10.5
|
1 - 11.3
|
||||||
2 - 10.4
|
2 - 10.8
|
||||||
3 - 10.3
|
3 - 9.6
|
||||||
4 - 10.2
|
4 - 9.5
|
||||||
5 - 10.1
|
5 - 9.4
|
||||||
6 - 9.6
|
Choose from 1, 2, 3, 4, 5 [1]: 1
|
||||||
7 - 9.5
|
|
||||||
8 - 9.4
|
|
||||||
Choose from 1, 2, 3, 4, 5, 6, 7, 8 [1]: 1
|
|
||||||
Select js_task_runner:
|
Select js_task_runner:
|
||||||
1 - None
|
1 - None
|
||||||
2 - Gulp
|
2 - Gulp
|
||||||
|
@ -185,7 +182,8 @@ Answer the prompts with your own desired options_. For example::
|
||||||
Select cloud_provider:
|
Select cloud_provider:
|
||||||
1 - AWS
|
1 - AWS
|
||||||
2 - GCS
|
2 - GCS
|
||||||
Choose from 1, 2 [1]: 1
|
3 - None
|
||||||
|
Choose from 1, 2, 3 [1]: 1
|
||||||
custom_bootstrap_compilation [n]: n
|
custom_bootstrap_compilation [n]: n
|
||||||
Select open_source_license:
|
Select open_source_license:
|
||||||
1 - MIT
|
1 - MIT
|
||||||
|
|
|
@ -18,11 +18,8 @@
|
||||||
"use_pycharm": "n",
|
"use_pycharm": "n",
|
||||||
"use_docker": "n",
|
"use_docker": "n",
|
||||||
"postgresql_version": [
|
"postgresql_version": [
|
||||||
"10.5",
|
"11.3",
|
||||||
"10.4",
|
"10.8",
|
||||||
"10.3",
|
|
||||||
"10.2",
|
|
||||||
"10.1",
|
|
||||||
"9.6",
|
"9.6",
|
||||||
"9.5",
|
"9.5",
|
||||||
"9.4"
|
"9.4"
|
||||||
|
@ -33,7 +30,8 @@
|
||||||
],
|
],
|
||||||
"cloud_provider": [
|
"cloud_provider": [
|
||||||
"AWS",
|
"AWS",
|
||||||
"GCE"
|
"GCE",
|
||||||
|
"None"
|
||||||
],
|
],
|
||||||
"custom_bootstrap_compilation": "n",
|
"custom_bootstrap_compilation": "n",
|
||||||
"use_compressor": "n",
|
"use_compressor": "n",
|
||||||
|
|
|
@ -35,7 +35,15 @@ Configuring the Stack
|
||||||
|
|
||||||
The majority of services above are configured through the use of environment variables. Just check out :ref:`envs` and you will know the drill.
|
The majority of services above are configured through the use of environment variables. Just check out :ref:`envs` and you will know the drill.
|
||||||
|
|
||||||
To obtain logs and information about crashes in a production setup, make sure that you have access to an external Sentry instance (e.g. by creating an account with `sentry.io`_), and set the ``SENTRY_DSN`` variable.
|
To obtain logs and information about crashes in a production setup, make sure that you have access to an external Sentry instance (e.g. by creating an account with `sentry.io`_), and set the ``SENTRY_DSN`` variable. Logs of level `logging.ERROR` are sent as Sentry events. Therefore, in order to send a Sentry event use:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import logging
|
||||||
|
logging.error("This event is sent to Sentry", extra={"<example_key>": "<example_value>"})
|
||||||
|
|
||||||
|
The `extra` parameter allows you to send additional information about the context of this error.
|
||||||
|
|
||||||
|
|
||||||
You will probably also need to setup the Mail backend, for example by adding a `Mailgun`_ API key and a `Mailgun`_ sender domain, otherwise, the account creation view will crash and result in a 500 error when the backend attempts to send an email to the account owner.
|
You will probably also need to setup the Mail backend, for example by adding a `Mailgun`_ API key and a `Mailgun`_ sender domain, otherwise, the account creation view will crash and result in a 500 error when the backend attempts to send an email to the account owner.
|
||||||
|
|
||||||
|
|
|
@ -49,14 +49,11 @@ use_docker:
|
||||||
postgresql_version:
|
postgresql_version:
|
||||||
Select a PostgreSQL_ version to use. The choices are:
|
Select a PostgreSQL_ version to use. The choices are:
|
||||||
|
|
||||||
1. 10.5
|
1. 11.3
|
||||||
2. 10.4
|
2. 10.8
|
||||||
3. 10.3
|
3. 9.6
|
||||||
4. 10.2
|
4. 9.5
|
||||||
5. 10.1
|
5. 9.4
|
||||||
6. 9.6
|
|
||||||
7. 9.5
|
|
||||||
8. 9.4
|
|
||||||
|
|
||||||
js_task_runner:
|
js_task_runner:
|
||||||
Select a JavaScript task runner. The choices are:
|
Select a JavaScript task runner. The choices are:
|
||||||
|
@ -69,6 +66,7 @@ cloud_provider:
|
||||||
|
|
||||||
1. AWS_
|
1. AWS_
|
||||||
2. GCS_
|
2. GCS_
|
||||||
|
3. None
|
||||||
|
|
||||||
custom_bootstrap_compilation:
|
custom_bootstrap_compilation:
|
||||||
Indicates whether the project should support Bootstrap recompilation
|
Indicates whether the project should support Bootstrap recompilation
|
||||||
|
@ -100,7 +98,7 @@ use_travisci:
|
||||||
keep_local_envs_in_vcs:
|
keep_local_envs_in_vcs:
|
||||||
Indicates whether the project's ``.envs/.local/`` should be kept in VCS
|
Indicates whether the project's ``.envs/.local/`` should be kept in VCS
|
||||||
(comes in handy when working in teams where local environment reproducibility
|
(comes in handy when working in teams where local environment reproducibility
|
||||||
is strongly encouraged).
|
is strongly encouraged).
|
||||||
Note: .env(s) are only utilized when Docker Compose and/or Heroku support is enabled.
|
Note: .env(s) are only utilized when Docker Compose and/or Heroku support is enabled.
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
|
|
|
@ -328,6 +328,12 @@ def main():
|
||||||
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
||||||
remove_node_dockerfile()
|
remove_node_dockerfile()
|
||||||
|
|
||||||
|
if "{{ cookiecutter.cloud_provider}}".lower() == "none":
|
||||||
|
print(
|
||||||
|
WARNING + "You chose not to use a cloud provider, "
|
||||||
|
"media files won't be served in production." + TERMINATOR
|
||||||
|
)
|
||||||
|
|
||||||
if "{{ cookiecutter.use_celery }}".lower() == "n":
|
if "{{ cookiecutter.use_celery }}".lower() == "n":
|
||||||
remove_celery_files()
|
remove_celery_files()
|
||||||
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
[pytest]
|
[pytest]
|
||||||
python_paths = .
|
python_paths = .
|
||||||
norecursedirs = .tox .git */migrations/* */static/* docs venv */{{cookiecutter.project_slug}}/*
|
norecursedirs = .tox .git */migrations/* */static/* docs venv */{{cookiecutter.project_slug}}/*
|
||||||
|
markers =
|
||||||
|
flake8: Run flake8 on all possible template combinations
|
||||||
|
black: Run black on all possible template combinations
|
||||||
|
|
|
@ -5,11 +5,11 @@ binaryornot==0.4.4
|
||||||
# Code quality
|
# Code quality
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
black==19.3b0
|
black==19.3b0
|
||||||
flake8==3.7.6
|
flake8==3.7.7
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
tox==3.11.1
|
tox==3.12.1
|
||||||
pytest==4.5.0
|
pytest==4.5.0
|
||||||
pytest_cases==1.6.2
|
pytest_cases==1.6.2
|
||||||
pytest-cookies==0.3.0
|
pytest-cookies==0.3.0
|
||||||
|
|
|
@ -7,11 +7,11 @@ import sh
|
||||||
import yaml
|
import yaml
|
||||||
from binaryornot.check import is_binary
|
from binaryornot.check import is_binary
|
||||||
|
|
||||||
PATTERN = "{{(\s?cookiecutter)[.](.*?)}}"
|
PATTERN = r"{{(\s?cookiecutter)[.](.*?)}}"
|
||||||
RE_OBJ = re.compile(PATTERN)
|
RE_OBJ = re.compile(PATTERN)
|
||||||
|
|
||||||
YN_CHOICES = ["y", "n"]
|
YN_CHOICES = ["y", "n"]
|
||||||
CLOUD_CHOICES = ["AWS", "GCE"]
|
CLOUD_CHOICES = ["AWS", "GCE", "None"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
|
@ -17,7 +17,7 @@ defaultEntryPoints = ["http", "https"]
|
||||||
[acme]
|
[acme]
|
||||||
# Email address used for registration
|
# Email address used for registration
|
||||||
email = "{{ cookiecutter.email }}"
|
email = "{{ cookiecutter.email }}"
|
||||||
storageFile = "/etc/traefik/acme/acme.json"
|
storage = "/etc/traefik/acme/acme.json"
|
||||||
entryPoint = "https"
|
entryPoint = "https"
|
||||||
onDemand = false
|
onDemand = false
|
||||||
OnHostRule = true
|
OnHostRule = true
|
||||||
|
|
|
@ -266,10 +266,10 @@ CELERY_TASK_SERIALIZER = "json"
|
||||||
CELERY_RESULT_SERIALIZER = "json"
|
CELERY_RESULT_SERIALIZER = "json"
|
||||||
# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-time-limit
|
# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-time-limit
|
||||||
# TODO: set to whatever value is adequate in your circumstances
|
# TODO: set to whatever value is adequate in your circumstances
|
||||||
CELERYD_TASK_TIME_LIMIT = 5 * 60
|
CELERY_TASK_TIME_LIMIT = 5 * 60
|
||||||
# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-soft-time-limit
|
# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-soft-time-limit
|
||||||
# TODO: set to whatever value is adequate in your circumstances
|
# TODO: set to whatever value is adequate in your circumstances
|
||||||
CELERYD_TASK_SOFT_TIME_LIMIT = 60
|
CELERY_TASK_SOFT_TIME_LIMIT = 60
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
# django-allauth
|
# django-allauth
|
||||||
|
|
|
@ -66,10 +66,12 @@ SECURE_CONTENT_TYPE_NOSNIFF = env.bool(
|
||||||
"DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True
|
"DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
{% if cookiecutter.cloud_provider != 'None' -%}
|
||||||
# STORAGES
|
# STORAGES
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://django-storages.readthedocs.io/en/latest/#installation
|
# https://django-storages.readthedocs.io/en/latest/#installation
|
||||||
INSTALLED_APPS += ["storages"] # noqa F405
|
INSTALLED_APPS += ["storages"] # noqa F405
|
||||||
|
{%- endif -%}
|
||||||
{% if cookiecutter.cloud_provider == 'AWS' %}
|
{% if cookiecutter.cloud_provider == 'AWS' %}
|
||||||
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
|
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
|
||||||
AWS_ACCESS_KEY_ID = env("DJANGO_AWS_ACCESS_KEY_ID")
|
AWS_ACCESS_KEY_ID = env("DJANGO_AWS_ACCESS_KEY_ID")
|
||||||
|
@ -93,19 +95,20 @@ AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None)
|
||||||
DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
|
DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
|
||||||
GS_BUCKET_NAME = env("DJANGO_GCE_STORAGE_BUCKET_NAME")
|
GS_BUCKET_NAME = env("DJANGO_GCE_STORAGE_BUCKET_NAME")
|
||||||
GS_DEFAULT_ACL = "publicRead"
|
GS_DEFAULT_ACL = "publicRead"
|
||||||
{% endif %}
|
{% endif -%}
|
||||||
|
|
||||||
|
{% if cookiecutter.cloud_provider != 'None' or cookiecutter.use_whitenoise == 'y' -%}
|
||||||
# STATIC
|
# STATIC
|
||||||
# ------------------------
|
# ------------------------
|
||||||
|
{% endif -%}
|
||||||
{% if cookiecutter.use_whitenoise == 'y' -%}
|
{% if cookiecutter.use_whitenoise == 'y' -%}
|
||||||
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
|
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
|
||||||
{%- endif -%}
|
{% elif cookiecutter.cloud_provider == 'AWS' -%}
|
||||||
{%- if cookiecutter.cloud_provider == 'AWS' %}
|
|
||||||
STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage"
|
STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage"
|
||||||
STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/"
|
STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/"
|
||||||
{%- elif cookiecutter.cloud_provider == 'GCE' %}
|
{% elif cookiecutter.cloud_provider == 'GCE' -%}
|
||||||
STATIC_URL = "https://storage.googleapis.com/{}/static/".format(GS_BUCKET_NAME)
|
STATIC_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/static/"
|
||||||
{%- endif %}
|
{% endif -%}
|
||||||
|
|
||||||
# MEDIA
|
# MEDIA
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -117,6 +120,7 @@ from storages.backends.s3boto3 import S3Boto3Storage # noqa E402
|
||||||
|
|
||||||
class StaticRootS3Boto3Storage(S3Boto3Storage):
|
class StaticRootS3Boto3Storage(S3Boto3Storage):
|
||||||
location = "static"
|
location = "static"
|
||||||
|
default_acl = "public-read"
|
||||||
|
|
||||||
|
|
||||||
class MediaRootS3Boto3Storage(S3Boto3Storage):
|
class MediaRootS3Boto3Storage(S3Boto3Storage):
|
||||||
|
@ -128,8 +132,8 @@ class MediaRootS3Boto3Storage(S3Boto3Storage):
|
||||||
DEFAULT_FILE_STORAGE = "config.settings.production.MediaRootS3Boto3Storage"
|
DEFAULT_FILE_STORAGE = "config.settings.production.MediaRootS3Boto3Storage"
|
||||||
MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/"
|
MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/"
|
||||||
{%- elif cookiecutter.cloud_provider == 'GCE' %}
|
{%- elif cookiecutter.cloud_provider == 'GCE' %}
|
||||||
MEDIA_URL = "https://storage.googleapis.com/{}/media/".format(GS_BUCKET_NAME)
|
MEDIA_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/media/"
|
||||||
MEDIA_ROOT = "https://storage.googleapis.com/{}/media/".format(GS_BUCKET_NAME)
|
MEDIA_ROOT = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/media/"
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
# TEMPLATES
|
# TEMPLATES
|
||||||
|
@ -193,7 +197,7 @@ COMPRESS_ENABLED = env.bool("COMPRESS_ENABLED", default=True)
|
||||||
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE
|
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE
|
||||||
COMPRESS_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
|
COMPRESS_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
|
||||||
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL
|
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL
|
||||||
COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' %} # noqa F405{% endif %}
|
COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %} # noqa F405{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%- if cookiecutter.use_whitenoise == 'n' -%}
|
{%- if cookiecutter.use_whitenoise == 'n' -%}
|
||||||
# Collectfast
|
# Collectfast
|
||||||
|
@ -288,7 +292,7 @@ SENTRY_LOG_LEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO)
|
||||||
|
|
||||||
sentry_logging = LoggingIntegration(
|
sentry_logging = LoggingIntegration(
|
||||||
level=SENTRY_LOG_LEVEL, # Capture info and above as breadcrumbs
|
level=SENTRY_LOG_LEVEL, # Capture info and above as breadcrumbs
|
||||||
event_level=None, # Send no events from log messages
|
event_level=logging.ERROR, # Send errors as events
|
||||||
)
|
)
|
||||||
|
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
|
|
|
@ -45,7 +45,7 @@ services:
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:3.2
|
image: redis:5.0
|
||||||
|
|
||||||
celeryworker:
|
celeryworker:
|
||||||
<<: *django
|
<<: *django
|
||||||
|
|
|
@ -44,7 +44,7 @@ services:
|
||||||
- "0.0.0.0:443:443"
|
- "0.0.0.0:443:443"
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:3.2
|
image: redis:5.0
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
|
|
||||||
celeryworker:
|
celeryworker:
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
-r ./base.txt
|
-r ./base.txt
|
||||||
|
|
||||||
Werkzeug==0.15.4 # https://github.com/pallets/werkzeug
|
Werkzeug==0.14.1 # pyup: < 0.15 # https://github.com/pallets/werkzeug
|
||||||
ipdb==0.12 # https://github.com/gotcha/ipdb
|
ipdb==0.12 # https://github.com/gotcha/ipdb
|
||||||
Sphinx==2.0.1 # https://github.com/sphinx-doc/sphinx
|
Sphinx==2.0.1 # https://github.com/sphinx-doc/sphinx
|
||||||
{%- if cookiecutter.use_docker == 'y' %}
|
{%- if cookiecutter.use_docker == 'y' %}
|
||||||
psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
|
psycopg2==2.8.2 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
|
||||||
{%- else %}
|
{%- else %}
|
||||||
psycopg2-binary==2.8.2 # https://github.com/psycopg/psycopg2
|
psycopg2-binary==2.8.2 # https://github.com/psycopg/psycopg2
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
@ -17,7 +17,7 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar
|
||||||
|
|
||||||
# Code quality
|
# Code quality
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
flake8==3.7.5 # https://github.com/PyCQA/flake8
|
flake8==3.7.7 # https://github.com/PyCQA/flake8
|
||||||
coverage==4.5.3 # https://github.com/nedbat/coveragepy
|
coverage==4.5.3 # https://github.com/nedbat/coveragepy
|
||||||
black==19.3b0 # https://github.com/ambv/black
|
black==19.3b0 # https://github.com/ambv/black
|
||||||
pylint-django==2.0.9 # https://github.com/PyCQA/pylint-django
|
pylint-django==2.0.9 # https://github.com/PyCQA/pylint-django
|
||||||
|
@ -30,6 +30,6 @@ pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery
|
||||||
factory-boy==2.12.0 # https://github.com/FactoryBoy/factory_boy
|
factory-boy==2.12.0 # https://github.com/FactoryBoy/factory_boy
|
||||||
|
|
||||||
django-debug-toolbar==1.11 # https://github.com/jazzband/django-debug-toolbar
|
django-debug-toolbar==1.11 # https://github.com/jazzband/django-debug-toolbar
|
||||||
django-extensions==2.1.6 # https://github.com/django-extensions/django-extensions
|
django-extensions==2.1.7 # https://github.com/django-extensions/django-extensions
|
||||||
django-coverage-plugin==1.6.0 # https://github.com/nedbat/django_coverage_plugin
|
django-coverage-plugin==1.6.0 # https://github.com/nedbat/django_coverage_plugin
|
||||||
pytest-django==3.4.8 # https://github.com/pytest-dev/pytest-django
|
pytest-django==3.4.8 # https://github.com/pytest-dev/pytest-django
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
-r ./base.txt
|
-r ./base.txt
|
||||||
|
|
||||||
gunicorn==19.9.0 # https://github.com/benoitc/gunicorn
|
gunicorn==19.9.0 # https://github.com/benoitc/gunicorn
|
||||||
psycopg2==2.8 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
|
psycopg2==2.8.2 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
|
||||||
{%- if cookiecutter.use_whitenoise == 'n' %}
|
{%- if cookiecutter.use_whitenoise == 'n' %}
|
||||||
Collectfast==0.6.2 # https://github.com/antonagestam/collectfast
|
Collectfast==0.6.2 # https://github.com/antonagestam/collectfast
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.use_sentry == "y" %}
|
{%- if cookiecutter.use_sentry == "y" %}
|
||||||
sentry-sdk==0.7.14 # https://github.com/getsentry/sentry-python
|
sentry-sdk==0.8.0 # https://github.com/getsentry/sentry-python
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
|
@ -18,4 +18,4 @@ django-storages[boto3]==1.7.1 # https://github.com/jschneier/django-storages
|
||||||
{%- elif cookiecutter.cloud_provider == 'GCE' %}
|
{%- elif cookiecutter.cloud_provider == 'GCE' %}
|
||||||
django-storages[google]==1.7.1 # https://github.com/jschneier/django-storages
|
django-storages[google]==1.7.1 # https://github.com/jschneier/django-storages
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
django-anymail[mailgun]==6.0 # https://github.com/anymail/django-anymail
|
django-anymail[mailgun]==6.0.1 # https://github.com/anymail/django-anymail
|
||||||
|
|
|
@ -13,11 +13,6 @@ def test_detail(user: settings.AUTH_USER_MODEL):
|
||||||
assert resolve(f"/users/{user.username}/").view_name == "users:detail"
|
assert resolve(f"/users/{user.username}/").view_name == "users:detail"
|
||||||
|
|
||||||
|
|
||||||
def test_list():
|
|
||||||
assert reverse("users:list") == "/users/"
|
|
||||||
assert resolve("/users/").view_name == "users:list"
|
|
||||||
|
|
||||||
|
|
||||||
def test_update():
|
def test_update():
|
||||||
assert reverse("users:update") == "/users/~update/"
|
assert reverse("users:update") == "/users/~update/"
|
||||||
assert resolve("/users/~update/").view_name == "users:update"
|
assert resolve("/users/~update/").view_name == "users:update"
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from {{ cookiecutter.project_slug }}.users.views import (
|
from {{ cookiecutter.project_slug }}.users.views import (
|
||||||
user_list_view,
|
|
||||||
user_redirect_view,
|
user_redirect_view,
|
||||||
user_update_view,
|
user_update_view,
|
||||||
user_detail_view,
|
user_detail_view,
|
||||||
|
@ -9,7 +8,6 @@ from {{ cookiecutter.project_slug }}.users.views import (
|
||||||
|
|
||||||
app_name = "users"
|
app_name = "users"
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", view=user_list_view, name="list"),
|
|
||||||
path("~redirect/", view=user_redirect_view, name="redirect"),
|
path("~redirect/", view=user_redirect_view, name="redirect"),
|
||||||
path("~update/", view=user_update_view, name="update"),
|
path("~update/", view=user_update_view, name="update"),
|
||||||
path("<str:username>/", view=user_detail_view, name="detail"),
|
path("<str:username>/", view=user_detail_view, name="detail"),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.views.generic import DetailView, ListView, RedirectView, UpdateView
|
from django.views.generic import DetailView, RedirectView, UpdateView
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
@ -16,16 +16,6 @@ class UserDetailView(LoginRequiredMixin, DetailView):
|
||||||
user_detail_view = UserDetailView.as_view()
|
user_detail_view = UserDetailView.as_view()
|
||||||
|
|
||||||
|
|
||||||
class UserListView(LoginRequiredMixin, ListView):
|
|
||||||
|
|
||||||
model = User
|
|
||||||
slug_field = "username"
|
|
||||||
slug_url_kwarg = "username"
|
|
||||||
|
|
||||||
|
|
||||||
user_list_view = UserListView.as_view()
|
|
||||||
|
|
||||||
|
|
||||||
class UserUpdateView(LoginRequiredMixin, UpdateView):
|
class UserUpdateView(LoginRequiredMixin, UpdateView):
|
||||||
|
|
||||||
model = User
|
model = User
|
||||||
|
|
Loading…
Reference in New Issue
Block a user