mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2024-11-25 02:54:01 +03:00
Merge remote-tracking branch 'origin/master' into update-doc
This commit is contained in:
commit
00772d7141
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -2,6 +2,19 @@
|
|||
All enhancements and patches to Cookiecutter Django will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [2020-01-12]
|
||||
### Changed
|
||||
- Fix mypy setup and added django-stubs
|
||||
- Add Gitlab CI as option
|
||||
|
||||
## [2020-01-11]
|
||||
### Changed
|
||||
- Speed up & reduce size for production Django image
|
||||
- Bumped runtime version for Heroku
|
||||
- Added Debian 10 (Buster) OS dependencies
|
||||
- Update Traefik to v2
|
||||
- Switched Docker images from Alpine based to Debian based
|
||||
|
||||
## [2019-10-06]
|
||||
### Changed
|
||||
- Default Python version is now 3.7 (@nicolas471)
|
||||
|
|
|
@ -71,6 +71,7 @@ Listed in alphabetical order.
|
|||
Benjamin Abel
|
||||
Bert de Miranda `@bertdemiranda`_
|
||||
Bo Lopker `@blopker`_
|
||||
Bo Peng `@BoPeng`_
|
||||
Bouke Haarsma
|
||||
Brent Payne `@brentpayne`_ @brentpayne
|
||||
Bruce Olivier `@bolivierjr`_
|
||||
|
@ -94,6 +95,7 @@ Listed in alphabetical order.
|
|||
Dan Shultz `@shultz`_
|
||||
Dani Hodovic `@danihodovic`_
|
||||
Daniel Hepper `@dhepper`_ @danielhepper
|
||||
Daniel Hillier `@danifus`_
|
||||
Daniele Tricoli `@eriol`_
|
||||
David Díaz `@ddiazpinto`_ @DavidDiazPinto
|
||||
Davit Tovmasyan `@davitovmasyan`_
|
||||
|
@ -102,6 +104,7 @@ Listed in alphabetical order.
|
|||
Demetris Stavrou `@demestav`_
|
||||
Denis Bobrov `@delneg`_
|
||||
Denis Orehovsky `@apirobot`_
|
||||
Denis Savran `@blaxpy`_
|
||||
Diane Chen `@purplediane`_ @purplediane88
|
||||
Dónal Adams `@epileptic-fish`_
|
||||
Dong Huynh `@trungdong`_
|
||||
|
@ -122,6 +125,8 @@ Listed in alphabetical order.
|
|||
Henrique G. G. Pereira `@ikkebr`_
|
||||
Ian Lee `@IanLee1521`_
|
||||
Irfan Ahmad `@erfaan`_ @erfaan
|
||||
Isaac12x `@Isaac12x`_
|
||||
Ivan Khomutov `@ikhomutov`_
|
||||
Jan Van Bruggen `@jvanbrug`_
|
||||
Jelmer Draaijer `@foarsitter`_
|
||||
Jens Nilsson `@phiberjenz`_
|
||||
|
@ -226,10 +231,12 @@ Listed in alphabetical order.
|
|||
.. _@arruda: https://github.com/arruda
|
||||
.. _@bertdemiranda: https://github.com/bertdemiranda
|
||||
.. _@bittner: https://github.com/bittner
|
||||
.. _@blaxpy: https://github.com/blaxpy
|
||||
.. _@bloodpet: https://github.com/bloodpet
|
||||
.. _@blopker: https://github.com/blopker
|
||||
.. _@bogdal: https://github.com/bogdal
|
||||
.. _@bolivierjr: https://github.com/bolivierjr
|
||||
.. _@BoPeng: https://github.com/BoPeng
|
||||
.. _@brentpayne: https://github.com/brentpayne
|
||||
.. _@btknu: https://github.com/btknu
|
||||
.. _@burhan: https://github.com/burhan
|
||||
|
@ -252,6 +259,7 @@ Listed in alphabetical order.
|
|||
.. _@curtisstpierre: https://github.com/curtisstpierre
|
||||
.. _@dadokkio: https://github.com/dadokkio
|
||||
.. _@danihodovic: https://github.com/danihodovic
|
||||
.. _@danifus: https://github.com/danifus
|
||||
.. _@davitovmasyan: https://github.com/davitovmasyan
|
||||
.. _@ddiazpinto: https://github.com/ddiazpinto
|
||||
.. _@delneg: https://github.com/delneg
|
||||
|
@ -281,7 +289,9 @@ Listed in alphabetical order.
|
|||
.. _@hendrikschneider: https://github.com/hendrikschneider
|
||||
.. _@hjwp: https://github.com/hjwp
|
||||
.. _@IanLee1521: https://github.com/IanLee1521
|
||||
.. _@ikhomutov: https://github.com/ikhomutov
|
||||
.. _@ikkebr: https://github.com/ikkebr
|
||||
.. _@Isaac12x: https://github.com/Isaac12x
|
||||
.. _@iynaix: https://github.com/iynaix
|
||||
.. _@jangeador: https://github.com/jangeador
|
||||
.. _@jazztpt: https://github.com/jazztpt
|
||||
|
|
|
@ -9,8 +9,8 @@ Cookiecutter Django
|
|||
:target: https://pyup.io/repos/github/pydanny/cookiecutter-django/
|
||||
:alt: Updates
|
||||
|
||||
.. 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://img.shields.io/badge/cookiecutter-Join%20on%20Slack-green?style=flat&logo=slack
|
||||
:target: https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U
|
||||
|
||||
.. image:: https://www.codetriage.com/pydanny/cookiecutter-django/badges/users.svg
|
||||
:target: https://www.codetriage.com/pydanny/cookiecutter-django
|
||||
|
@ -226,11 +226,11 @@ Community
|
|||
|
||||
* Have questions? **Before you ask questions anywhere else**, please post your question on `Stack Overflow`_ under the *cookiecutter-django* tag. We check there periodically for questions.
|
||||
* If you think you found a bug or want to request a feature, please open an issue_.
|
||||
* For anything else, you can chat with us on `Gitter`_.
|
||||
* For anything else, you can chat with us on `Slack`_.
|
||||
|
||||
.. _`Stack Overflow`: http://stackoverflow.com/questions/tagged/cookiecutter-django
|
||||
.. _`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
|
||||
.. _`Slack`: https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U
|
||||
|
||||
For Readers of Two Scoops of Django
|
||||
--------------------------------------------
|
||||
|
|
|
@ -40,7 +40,11 @@
|
|||
"use_sentry": "n",
|
||||
"use_whitenoise": "n",
|
||||
"use_heroku": "n",
|
||||
"use_travisci": "n",
|
||||
"ci_tool": [
|
||||
"None",
|
||||
"Travis",
|
||||
"Gitlab"
|
||||
],
|
||||
"keep_local_envs_in_vcs": "y",
|
||||
|
||||
"debug": "n"
|
||||
|
|
|
@ -94,8 +94,12 @@ use_heroku:
|
|||
Indicates whether the project should be configured so as to be deployable
|
||||
to Heroku_.
|
||||
|
||||
use_travisci:
|
||||
Indicates whether the project should be configured to use `Travis CI`_.
|
||||
ci_tool:
|
||||
Select a CI tool for running tests. The choices are:
|
||||
|
||||
1. None
|
||||
2. Travis_
|
||||
3. Gitlab_
|
||||
|
||||
keep_local_envs_in_vcs:
|
||||
Indicates whether the project's ``.envs/.local/`` should be kept in VCS
|
||||
|
@ -138,3 +142,6 @@ debug:
|
|||
.. _Heroku: https://github.com/heroku/heroku-buildpack-python
|
||||
|
||||
.. _Travis CI: https://travis-ci.org/
|
||||
|
||||
.. _GitLab CI: https://docs.gitlab.com/ee/ci/
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ Once the tests are complete, in order to see the code coverage, run the followin
|
|||
Since this is a fresh install, and there are no tests built using the Python `unittest`_ library yet, you should get feedback that says there were no tests carried out.
|
||||
|
||||
.. _Pytest: https://docs.pytest.org/en/latest/example/simple.html
|
||||
.. _develop locally: ../developing-locally.rst
|
||||
.. _develop locally with docker: ..../developing-locally-docker.rst
|
||||
.. _develop locally: ./developing-locally.html
|
||||
.. _develop locally with docker: ./developing-locally-docker.html
|
||||
.. _customize: https://docs.pytest.org/en/latest/customize.html
|
||||
.. _unittest: https://docs.python.org/3/library/unittest.html#module-unittest
|
||||
.. _configuring: https://coverage.readthedocs.io/en/v4.5.x/config.html
|
||||
.. _configuring: https://coverage.readthedocs.io/en/v4.5.x/config.html
|
||||
|
|
|
@ -70,7 +70,7 @@ def remove_heroku_files():
|
|||
for file_name in file_names:
|
||||
if (
|
||||
file_name == "requirements.txt"
|
||||
and "{{ cookiecutter.use_travisci }}".lower() == "y"
|
||||
and "{{ cookiecutter.ci_tool }}".lower() == "travis"
|
||||
):
|
||||
# don't remove the file if we are using travisci but not using heroku
|
||||
continue
|
||||
|
@ -105,6 +105,10 @@ def remove_dottravisyml_file():
|
|||
os.remove(".travis.yml")
|
||||
|
||||
|
||||
def remove_dotgitlabciyml_file():
|
||||
os.remove(".gitlab-ci.yml")
|
||||
|
||||
|
||||
def append_to_project_gitignore(path):
|
||||
gitignore_file_path = ".gitignore"
|
||||
with open(gitignore_file_path, "a") as gitignore_file:
|
||||
|
@ -349,9 +353,12 @@ def main():
|
|||
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
||||
remove_celery_compose_dirs()
|
||||
|
||||
if "{{ cookiecutter.use_travisci }}".lower() == "n":
|
||||
if "{{ cookiecutter.ci_tool }}".lower() != "travis":
|
||||
remove_dottravisyml_file()
|
||||
|
||||
if "{{ cookiecutter.ci_tool }}".lower() != "gitlab":
|
||||
remove_dotgitlabciyml_file()
|
||||
|
||||
print(SUCCESS + "Project initialized, keep up the good work!" + TERMINATOR)
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cookiecutter==1.6.0
|
||||
cookiecutter==1.7.0
|
||||
sh==1.12.14
|
||||
binaryornot==0.4.4
|
||||
|
||||
|
@ -9,9 +9,9 @@ flake8==3.7.9
|
|||
|
||||
# Testing
|
||||
# ------------------------------------------------------------------------------
|
||||
tox==3.14.2
|
||||
pytest==5.3.2
|
||||
tox==3.14.3
|
||||
pytest==5.3.4
|
||||
pytest_cases==1.12.0
|
||||
pytest-cookies==0.4.0
|
||||
pytest-xdist==1.31.0
|
||||
pyyaml==5.2
|
||||
pyyaml==5.3
|
||||
|
|
|
@ -140,7 +140,7 @@ def test_black_passes(cookies, context_combination):
|
|||
|
||||
|
||||
def test_travis_invokes_pytest(cookies, context):
|
||||
context.update({"use_travisci": "y"})
|
||||
context.update({"ci_tool": "Travis"})
|
||||
result = cookies.bake(extra_context=context)
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
@ -155,6 +155,24 @@ def test_travis_invokes_pytest(cookies, context):
|
|||
pytest.fail(e)
|
||||
|
||||
|
||||
def test_gitlab_invokes_flake8_and_pytest(cookies, context):
|
||||
context.update({"ci_tool": "Gitlab"})
|
||||
result = cookies.bake(extra_context=context)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert result.exception is None
|
||||
assert result.project.basename == context["project_slug"]
|
||||
assert result.project.isdir()
|
||||
|
||||
with open(f"{result.project}/.gitlab-ci.yml", "r") as gitlab_yml:
|
||||
try:
|
||||
gitlab_config = yaml.load(gitlab_yml)
|
||||
assert gitlab_config["flake8"]["script"] == ["flake8"]
|
||||
assert gitlab_config["pytest"]["script"] == ["pytest"]
|
||||
except yaml.YAMLError as e:
|
||||
pytest.fail(e)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("slug", ["project slug", "Project_Slug"])
|
||||
def test_invalid_slug(cookies, context, slug):
|
||||
"""Invalid slug should failed pre-generation hook."""
|
||||
|
|
33
{{cookiecutter.project_slug}}/.gitlab-ci.yml
Normal file
33
{{cookiecutter.project_slug}}/.gitlab-ci.yml
Normal file
|
@ -0,0 +1,33 @@
|
|||
stages:
|
||||
- lint
|
||||
- test
|
||||
|
||||
variables:
|
||||
POSTGRES_USER: '{{ cookiecutter.project_slug }}'
|
||||
POSTGRES_PASSWORD: ''
|
||||
POSTGRES_DB: 'test_{{ cookiecutter.project_slug }}'
|
||||
|
||||
flake8:
|
||||
stage: lint
|
||||
image: python:3.7-alpine
|
||||
before_script:
|
||||
- pip install -q flake8
|
||||
script:
|
||||
- flake8
|
||||
|
||||
pytest:
|
||||
stage: test
|
||||
image: python:3.7
|
||||
tags:
|
||||
- docker
|
||||
services:
|
||||
- postgres:11
|
||||
variables:
|
||||
DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB
|
||||
|
||||
before_script:
|
||||
- pip install -r requirements/local.txt
|
||||
|
||||
script:
|
||||
- pytest
|
||||
|
|
@ -1,19 +1,17 @@
|
|||
FROM python:3.7-alpine
|
||||
FROM python:3.7-slim-buster
|
||||
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
|
||||
RUN apk update \
|
||||
RUN apt-get update \
|
||||
# dependencies for building Python packages
|
||||
&& apt-get install -y build-essential \
|
||||
# psycopg2 dependencies
|
||||
&& apk add --virtual build-deps gcc python3-dev musl-dev \
|
||||
&& apk add postgresql-dev \
|
||||
# Pillow dependencies
|
||||
&& apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
|
||||
# CFFI dependencies
|
||||
&& apk add libffi-dev py-cffi \
|
||||
&& apt-get install -y libpq-dev \
|
||||
# Translations dependencies
|
||||
&& apk add gettext \
|
||||
# https://docs.djangoproject.com/en/dev/ref/django-admin/#dbshell
|
||||
&& apk add postgresql-client
|
||||
&& apt-get install -y gettext \
|
||||
# cleaning up unused files
|
||||
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Requirements are installed here to ensure they will be cached.
|
||||
COPY ./requirements /requirements
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
|
|
@ -9,21 +9,23 @@ RUN npm run build
|
|||
|
||||
# Python build stage
|
||||
{%- endif %}
|
||||
FROM python:3.7-alpine
|
||||
FROM python:3.7-slim-buster
|
||||
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
|
||||
RUN apk update \
|
||||
RUN apt-get update \
|
||||
# dependencies for building Python packages
|
||||
&& apt-get install -y build-essential \
|
||||
# psycopg2 dependencies
|
||||
&& apk add --virtual build-deps gcc python3-dev musl-dev \
|
||||
&& apk add postgresql-dev \
|
||||
# Pillow dependencies
|
||||
&& apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
|
||||
# CFFI dependencies
|
||||
&& apk add libffi-dev py-cffi
|
||||
&& apt-get install -y libpq-dev \
|
||||
# Translations dependencies
|
||||
&& apt-get install -y gettext \
|
||||
# cleaning up unused files
|
||||
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN addgroup -S django \
|
||||
&& adduser -S -G django django
|
||||
RUN addgroup --system django \
|
||||
&& adduser --system --ingroup django django
|
||||
|
||||
# Requirements are installed here to ensure they will be cached.
|
||||
COPY ./requirements /requirements
|
||||
|
@ -57,13 +59,11 @@ RUN chmod +x /start-flower
|
|||
{%- endif %}
|
||||
|
||||
{%- if cookiecutter.js_task_runner == 'Gulp' %}
|
||||
COPY --from=client-builder /app /app
|
||||
COPY --from=client-builder --chown=django:django /app /app
|
||||
{% else %}
|
||||
COPY . /app
|
||||
COPY --chown=django:django . /app
|
||||
{%- endif %}
|
||||
|
||||
RUN chown -R django /app
|
||||
|
||||
USER django
|
||||
|
||||
WORKDIR /app
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
FROM traefik:1.7-alpine
|
||||
FROM traefik:v2.0
|
||||
RUN mkdir -p /etc/traefik/acme
|
||||
RUN touch /etc/traefik/acme/acme.json
|
||||
RUN chmod 600 /etc/traefik/acme/acme.json
|
||||
COPY ./compose/production/traefik/traefik.toml /etc/traefik
|
||||
COPY ./compose/production/traefik/traefik.yml /etc/traefik
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
logLevel = "INFO"
|
||||
defaultEntryPoints = ["http", "https"]
|
||||
|
||||
# Entrypoints, http and https
|
||||
[entryPoints]
|
||||
# http should be redirected to https
|
||||
[entryPoints.http]
|
||||
address = ":80"
|
||||
[entryPoints.http.redirect]
|
||||
entryPoint = "https"
|
||||
# https is the default
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
[entryPoints.https.tls]
|
||||
|
||||
# Enable ACME (Let's Encrypt): automatic SSL
|
||||
[acme]
|
||||
# Email address used for registration
|
||||
email = "{{ cookiecutter.email }}"
|
||||
storage = "/etc/traefik/acme/acme.json"
|
||||
entryPoint = "https"
|
||||
onDemand = false
|
||||
OnHostRule = true
|
||||
# Use a HTTP-01 acme challenge rather than TLS-SNI-01 challenge
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "http"
|
||||
|
||||
[file]
|
||||
[backends]
|
||||
[backends.django]
|
||||
[backends.django.servers.server1]
|
||||
url = "http://django:5000"
|
||||
|
||||
[frontends]
|
||||
[frontends.django]
|
||||
backend = "django"
|
||||
passHostHeader = true
|
||||
[frontends.django.headers]
|
||||
HostsProxyHeaders = ['X-CSRFToken']
|
||||
[frontends.django.routes.dr1]
|
||||
rule = "Host:{{ cookiecutter.domain_name }}"
|
|
@ -0,0 +1,67 @@
|
|||
log:
|
||||
level: INFO
|
||||
|
||||
entryPoints:
|
||||
web:
|
||||
# http
|
||||
address: ":80"
|
||||
|
||||
web-secure:
|
||||
# https
|
||||
address: ":443"
|
||||
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
# https://docs.traefik.io/master/https/acme/#lets-encrypt
|
||||
acme:
|
||||
email: "{{ cookiecutter.email }}"
|
||||
storage: /etc/traefik/acme/acme.json
|
||||
# https://docs.traefik.io/master/https/acme/#httpchallenge
|
||||
httpChallenge:
|
||||
entryPoint: web
|
||||
|
||||
http:
|
||||
routers:
|
||||
web-router:
|
||||
rule: "Host(`{{ cookiecutter.domain_name }}`)"
|
||||
entryPoints:
|
||||
- web
|
||||
middlewares:
|
||||
- redirect
|
||||
- csrf
|
||||
service: django
|
||||
|
||||
web-secure-router:
|
||||
rule: "Host(`{{ cookiecutter.domain_name }}`)"
|
||||
entryPoints:
|
||||
- web-secure
|
||||
middlewares:
|
||||
- csrf
|
||||
service: django
|
||||
tls:
|
||||
# https://docs.traefik.io/master/routing/routers/#certresolver
|
||||
certResolver: letsencrypt
|
||||
|
||||
middlewares:
|
||||
redirect:
|
||||
# https://docs.traefik.io/master/middlewares/redirectscheme/
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
csrf:
|
||||
# https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders
|
||||
# https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
|
||||
headers:
|
||||
hostsProxyHeaders: ['X-CSRFToken']
|
||||
|
||||
services:
|
||||
django:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://django:5000
|
||||
|
||||
providers:
|
||||
# https://docs.traefik.io/master/providers/file/
|
||||
file:
|
||||
filename: /etc/traefik/traefik.yml
|
||||
watch: true
|
|
@ -140,6 +140,7 @@ MIDDLEWARE = [
|
|||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.common.BrokenLinkEmailsMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ MEDIA_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/media/"
|
|||
# TEMPLATES
|
||||
# ------------------------------------------------------------------------------
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#templates
|
||||
TEMPLATES[0]["OPTIONS"]["loaders"] = [ # noqa F405
|
||||
TEMPLATES[-1]["OPTIONS"]["loaders"] = [ # type: ignore[index] # noqa F405
|
||||
(
|
||||
"django.template.loaders.cached.Loader",
|
||||
[
|
||||
|
|
|
@ -32,7 +32,7 @@ PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"]
|
|||
|
||||
# TEMPLATES
|
||||
# ------------------------------------------------------------------------------
|
||||
TEMPLATES[0]["OPTIONS"]["loaders"] = [ # noqa F405
|
||||
TEMPLATES[-1]["OPTIONS"]["loaders"] = [ # type: ignore[index] # noqa F405
|
||||
(
|
||||
"django.template.loaders.cached.Loader",
|
||||
[
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
pytz==2019.3 # https://github.com/stub42/pytz
|
||||
python-slugify==4.0.0 # https://github.com/un33k/python-slugify
|
||||
Pillow==6.2.1 # https://github.com/python-pillow/Pillow
|
||||
Pillow==7.0.0 # https://github.com/python-pillow/Pillow
|
||||
{%- if cookiecutter.use_compressor == "y" %}
|
||||
rcssmin==1.0.6{% if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin
|
||||
{%- endif %}
|
||||
|
@ -25,7 +25,7 @@ django-model-utils==4.0.0 # https://github.com/jazzband/django-model-utils
|
|||
django-allauth==0.41.0 # https://github.com/pennersr/django-allauth
|
||||
django-crispy-forms==1.8.1 # https://github.com/django-crispy-forms/django-crispy-forms
|
||||
{%- if cookiecutter.use_compressor == "y" %}
|
||||
django-compressor==2.3 # https://github.com/django-compressor/django-compressor
|
||||
django-compressor==2.4 # https://github.com/django-compressor/django-compressor
|
||||
{%- endif %}
|
||||
django-redis==4.11.0 # https://github.com/niwinz/django-redis
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
Werkzeug==0.16.0 # https://github.com/pallets/werkzeug
|
||||
ipdb==0.12.3 # https://github.com/gotcha/ipdb
|
||||
Sphinx==2.3.0 # https://github.com/sphinx-doc/sphinx
|
||||
Sphinx==2.3.1 # https://github.com/sphinx-doc/sphinx
|
||||
{%- if cookiecutter.use_docker == 'y' %}
|
||||
psycopg2==2.8.3 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
|
||||
psycopg2==2.8.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
|
||||
{%- else %}
|
||||
psycopg2-binary==2.8.4 # https://github.com/psycopg/psycopg2
|
||||
{%- endif %}
|
||||
|
@ -12,25 +12,26 @@ psycopg2-binary==2.8.4 # https://github.com/psycopg/psycopg2
|
|||
# Testing
|
||||
# ------------------------------------------------------------------------------
|
||||
mypy==0.761 # https://github.com/python/mypy
|
||||
pytest==5.3.1 # https://github.com/pytest-dev/pytest
|
||||
django-stubs==1.4.0 # https://github.com/typeddjango/django-stubs
|
||||
pytest==5.3.4 # https://github.com/pytest-dev/pytest
|
||||
pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar
|
||||
|
||||
# Code quality
|
||||
# ------------------------------------------------------------------------------
|
||||
flake8==3.7.9 # https://github.com/PyCQA/flake8
|
||||
coverage==5.0 # https://github.com/nedbat/coveragepy
|
||||
coverage==5.0.3 # https://github.com/nedbat/coveragepy
|
||||
black==19.10b0 # https://github.com/ambv/black
|
||||
pylint-django==2.0.13 # https://github.com/PyCQA/pylint-django
|
||||
{%- if cookiecutter.use_celery == 'y' %}
|
||||
pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery
|
||||
{%- endif %}
|
||||
pre-commit==1.20.0 # https://github.com/pre-commit/pre-commit
|
||||
pre-commit==1.21.0 # https://github.com/pre-commit/pre-commit
|
||||
|
||||
# Django
|
||||
# ------------------------------------------------------------------------------
|
||||
factory-boy==2.12.0 # https://github.com/FactoryBoy/factory_boy
|
||||
|
||||
django-debug-toolbar==2.1 # https://github.com/jazzband/django-debug-toolbar
|
||||
django-extensions==2.2.5 # https://github.com/django-extensions/django-extensions
|
||||
django-coverage-plugin==1.6.0 # https://github.com/nedbat/django_coverage_plugin
|
||||
pytest-django==3.7.0 # https://github.com/pytest-dev/pytest-django
|
||||
django-extensions==2.2.6 # https://github.com/django-extensions/django-extensions
|
||||
django-coverage-plugin==1.7.0 # https://github.com/nedbat/django_coverage_plugin
|
||||
pytest-django==3.8.0 # https://github.com/pytest-dev/pytest-django
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
-r ./base.txt
|
||||
|
||||
gunicorn==20.0.4 # https://github.com/benoitc/gunicorn
|
||||
psycopg2==2.8.3 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
|
||||
psycopg2==2.8.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
|
||||
{%- if cookiecutter.use_whitenoise == 'n' %}
|
||||
Collectfast==1.3.1 # https://github.com/antonagestam/collectfast
|
||||
{%- endif %}
|
||||
{%- if cookiecutter.use_sentry == "y" %}
|
||||
sentry-sdk==0.13.5 # https://github.com/getsentry/sentry-python
|
||||
sentry-sdk==0.14.1 # https://github.com/getsentry/sentry-python
|
||||
{%- endif %}
|
||||
|
||||
# Django
|
||||
|
|
|
@ -1 +1 @@
|
|||
python-3.7.4
|
||||
python-3.7.6
|
||||
|
|
|
@ -13,6 +13,7 @@ ignore_missing_imports = True
|
|||
warn_unused_ignores = True
|
||||
warn_redundant_casts = True
|
||||
warn_unused_configs = True
|
||||
plugins = mypy_django_plugin.main
|
||||
|
||||
[mypy.plugins.django-stubs]
|
||||
django_settings_module = config.settings.test
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
##basic build dependencies of various Django apps for Debian Jessie 10.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
|
||||
libgraphviz-dev
|
|
@ -1,7 +1,7 @@
|
|||
import pytest
|
||||
from django.conf import settings
|
||||
from django.test import RequestFactory
|
||||
|
||||
from {{ cookiecutter.project_slug }}.users.models import User
|
||||
from {{ cookiecutter.project_slug }}.users.tests.factories import UserFactory
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@ def media_storage(settings, tmpdir):
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def user() -> settings.AUTH_USER_MODEL:
|
||||
def user() -> User:
|
||||
return UserFactory()
|
||||
|
||||
|
||||
|
|
|
@ -12,14 +12,18 @@ class UserFactory(DjangoModelFactory):
|
|||
|
||||
@post_generation
|
||||
def password(self, create: bool, extracted: Sequence[Any], **kwargs):
|
||||
password = Faker(
|
||||
"password",
|
||||
length=42,
|
||||
special_chars=True,
|
||||
digits=True,
|
||||
upper_case=True,
|
||||
lower_case=True,
|
||||
).generate(extra_kwargs={})
|
||||
password = (
|
||||
extracted
|
||||
if extracted
|
||||
else Faker(
|
||||
"password",
|
||||
length=42,
|
||||
special_chars=True,
|
||||
digits=True,
|
||||
upper_case=True,
|
||||
lower_case=True,
|
||||
).generate(extra_kwargs={})
|
||||
)
|
||||
self.set_password(password)
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import pytest
|
||||
from django.conf import settings
|
||||
|
||||
from {{ cookiecutter.project_slug }}.users.models import User
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_user_get_absolute_url(user: settings.AUTH_USER_MODEL):
|
||||
def test_user_get_absolute_url(user: User):
|
||||
assert user.get_absolute_url() == f"/users/{user.username}/"
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import pytest
|
||||
from django.conf import settings
|
||||
from django.urls import reverse, resolve
|
||||
|
||||
from {{ cookiecutter.project_slug }}.users.models import User
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_detail(user: settings.AUTH_USER_MODEL):
|
||||
def test_detail(user: User):
|
||||
assert (
|
||||
reverse("users:detail", kwargs={"username": user.username})
|
||||
== f"/users/{user.username}/"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import pytest
|
||||
from django.conf import settings
|
||||
from django.test import RequestFactory
|
||||
|
||||
from {{ cookiecutter.project_slug }}.users.models import User
|
||||
from {{ cookiecutter.project_slug }}.users.views import UserRedirectView, UserUpdateView
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
@ -16,9 +16,7 @@ class TestUserUpdateView:
|
|||
https://github.com/pytest-dev/pytest-django/pull/258
|
||||
"""
|
||||
|
||||
def test_get_success_url(
|
||||
self, user: settings.AUTH_USER_MODEL, request_factory: RequestFactory
|
||||
):
|
||||
def test_get_success_url(self, user: User, request_factory: RequestFactory):
|
||||
view = UserUpdateView()
|
||||
request = request_factory.get("/fake-url/")
|
||||
request.user = user
|
||||
|
@ -27,9 +25,7 @@ class TestUserUpdateView:
|
|||
|
||||
assert view.get_success_url() == f"/users/{user.username}/"
|
||||
|
||||
def test_get_object(
|
||||
self, user: settings.AUTH_USER_MODEL, request_factory: RequestFactory
|
||||
):
|
||||
def test_get_object(self, user: User, request_factory: RequestFactory):
|
||||
view = UserUpdateView()
|
||||
request = request_factory.get("/fake-url/")
|
||||
request.user = user
|
||||
|
@ -40,9 +36,7 @@ class TestUserUpdateView:
|
|||
|
||||
|
||||
class TestUserRedirectView:
|
||||
def test_get_redirect_url(
|
||||
self, user: settings.AUTH_USER_MODEL, request_factory: RequestFactory
|
||||
):
|
||||
def test_get_redirect_url(self, user: User, request_factory: RequestFactory):
|
||||
view = UserRedirectView()
|
||||
request = request_factory.get("/fake-url")
|
||||
request.user = user
|
||||
|
|
Loading…
Reference in New Issue
Block a user