mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2025-02-03 13:14:28 +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.
|
||||
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]
|
||||
### Fixed
|
||||
- Added `LocaleMiddleware` to the list of middlewares (@tanoabeleyra)
|
||||
|
|
|
@ -7,19 +7,19 @@ 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
|
||||
Saurabh Kumar `@theskumar`_ @_theskumar
|
||||
=========================== ================= ===========
|
||||
Name Github Twitter
|
||||
=========================== ================= ===========
|
||||
Daniel Roy Greenfeld `@pydanny`_ @pydanny
|
||||
Audrey Roy Greenfeld* `@audreyr`_ @audreyr
|
||||
Fábio C. Barrionuevo da Luz `@luzfcb`_ @luzfcb
|
||||
Saurabh Kumar `@theskumar`_ @_theskumar
|
||||
Jannis Gebauer `@jayfk`_
|
||||
Burhan Khalid `@burhan`_ @burhan
|
||||
Nikita Shupeyko `@webyneter`_ @webyneter
|
||||
Bruno Alla `@browniebroke`_ @_BrunoAlla
|
||||
Wan Liuyang `@sfdye`_ @sfdye
|
||||
=========================== ================ ===========
|
||||
Burhan Khalid `@burhan`_ @burhan
|
||||
Nikita Shupeyko `@webyneter`_ @webyneter
|
||||
Bruno Alla `@browniebroke`_ @_BrunoAlla
|
||||
Wan Liuyang `@sfdye`_ @sfdye
|
||||
=========================== ================= ===========
|
||||
|
||||
*Audrey is also the creator of Cookiecutter. Audrey and
|
||||
Daniel are on the Cookiecutter core team.*
|
||||
|
@ -87,6 +87,7 @@ Listed in alphabetical order.
|
|||
Craig Margieson `@cmargieson`_
|
||||
Cristian Vargas `@cdvv7788`_
|
||||
Cullen Rhodes `@c-rhodes`_
|
||||
Curtis St Pierre `@curtisstpierre`_ @cstpierre1388
|
||||
Dan Shultz `@shultz`_
|
||||
Daniel Hepper `@dhepper`_ @danielhepper
|
||||
Daniele Tricoli `@eriol`_
|
||||
|
@ -143,6 +144,7 @@ Listed in alphabetical order.
|
|||
Mateusz Ostaszewski `@mostaszewski`_
|
||||
Mathijs Hoogland `@MathijsHoogland`_
|
||||
Matt Braymer-Hayes `@mattayes`_ @mattayes
|
||||
Matt Knapper `@mknapper1`_
|
||||
Matt Linares
|
||||
Matt Menzenski `@menzenski`_
|
||||
Matt Warren `@mfwarren`_
|
||||
|
@ -221,6 +223,7 @@ Listed in alphabetical order.
|
|||
.. _@chuckus: https://github.com/chuckus
|
||||
.. _@cmackenzie1: https://github.com/cmackenzie1
|
||||
.. _@Collederas: https://github.com/Collederas
|
||||
.. _@curtisstpierre: https://github.com/curtisstpierre
|
||||
.. _@davitovmasyan: https://github.com/davitovmasyan
|
||||
.. _@ddiazpinto: https://github.com/ddiazpinto
|
||||
.. _@demestav: https://github.com/demestav
|
||||
|
@ -260,6 +263,7 @@ Listed in alphabetical order.
|
|||
.. _@msaizar: https://github.com/msaizar
|
||||
.. _@MathijsHoogland: https://github.com/MathijsHoogland
|
||||
.. _@mattayes: https://github.com/mattayes
|
||||
.. _@mknapper1: https://github.com/mknapper1
|
||||
.. _@menzenski: https://github.com/menzenski
|
||||
.. _@mostaszewski: https://github.com/mostaszewski
|
||||
.. _@mfwarren: https://github.com/mfwarren
|
||||
|
|
20
README.rst
20
README.rst
|
@ -89,7 +89,7 @@ Constraints
|
|||
-----------
|
||||
|
||||
* 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).
|
||||
|
||||
Support this Project!
|
||||
|
@ -169,15 +169,12 @@ Answer the prompts with your own desired options_. For example::
|
|||
use_heroku [n]: y
|
||||
use_compressor [n]: y
|
||||
Select postgresql_version:
|
||||
1 - 10.5
|
||||
2 - 10.4
|
||||
3 - 10.3
|
||||
4 - 10.2
|
||||
5 - 10.1
|
||||
6 - 9.6
|
||||
7 - 9.5
|
||||
8 - 9.4
|
||||
Choose from 1, 2, 3, 4, 5, 6, 7, 8 [1]: 1
|
||||
1 - 11.3
|
||||
2 - 10.8
|
||||
3 - 9.6
|
||||
4 - 9.5
|
||||
5 - 9.4
|
||||
Choose from 1, 2, 3, 4, 5 [1]: 1
|
||||
Select js_task_runner:
|
||||
1 - None
|
||||
2 - Gulp
|
||||
|
@ -185,7 +182,8 @@ Answer the prompts with your own desired options_. For example::
|
|||
Select cloud_provider:
|
||||
1 - AWS
|
||||
2 - GCS
|
||||
Choose from 1, 2 [1]: 1
|
||||
3 - None
|
||||
Choose from 1, 2, 3 [1]: 1
|
||||
custom_bootstrap_compilation [n]: n
|
||||
Select open_source_license:
|
||||
1 - MIT
|
||||
|
|
|
@ -18,11 +18,8 @@
|
|||
"use_pycharm": "n",
|
||||
"use_docker": "n",
|
||||
"postgresql_version": [
|
||||
"10.5",
|
||||
"10.4",
|
||||
"10.3",
|
||||
"10.2",
|
||||
"10.1",
|
||||
"11.3",
|
||||
"10.8",
|
||||
"9.6",
|
||||
"9.5",
|
||||
"9.4"
|
||||
|
@ -33,7 +30,8 @@
|
|||
],
|
||||
"cloud_provider": [
|
||||
"AWS",
|
||||
"GCE"
|
||||
"GCE",
|
||||
"None"
|
||||
],
|
||||
"custom_bootstrap_compilation": "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.
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -49,14 +49,11 @@ use_docker:
|
|||
postgresql_version:
|
||||
Select a PostgreSQL_ version to use. The choices are:
|
||||
|
||||
1. 10.5
|
||||
2. 10.4
|
||||
3. 10.3
|
||||
4. 10.2
|
||||
5. 10.1
|
||||
6. 9.6
|
||||
7. 9.5
|
||||
8. 9.4
|
||||
1. 11.3
|
||||
2. 10.8
|
||||
3. 9.6
|
||||
4. 9.5
|
||||
5. 9.4
|
||||
|
||||
js_task_runner:
|
||||
Select a JavaScript task runner. The choices are:
|
||||
|
@ -69,6 +66,7 @@ cloud_provider:
|
|||
|
||||
1. AWS_
|
||||
2. GCS_
|
||||
3. None
|
||||
|
||||
custom_bootstrap_compilation:
|
||||
Indicates whether the project should support Bootstrap recompilation
|
||||
|
@ -100,7 +98,7 @@ use_travisci:
|
|||
keep_local_envs_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
|
||||
is strongly encouraged).
|
||||
is strongly encouraged).
|
||||
Note: .env(s) are only utilized when Docker Compose and/or Heroku support is enabled.
|
||||
|
||||
debug:
|
||||
|
|
|
@ -328,6 +328,12 @@ def main():
|
|||
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
||||
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":
|
||||
remove_celery_files()
|
||||
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
[pytest]
|
||||
python_paths = .
|
||||
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
|
||||
# ------------------------------------------------------------------------------
|
||||
black==19.3b0
|
||||
flake8==3.7.6
|
||||
flake8==3.7.7
|
||||
|
||||
# Testing
|
||||
# ------------------------------------------------------------------------------
|
||||
tox==3.11.1
|
||||
tox==3.12.1
|
||||
pytest==4.5.0
|
||||
pytest_cases==1.6.2
|
||||
pytest-cookies==0.3.0
|
||||
|
|
|
@ -7,11 +7,11 @@ import sh
|
|||
import yaml
|
||||
from binaryornot.check import is_binary
|
||||
|
||||
PATTERN = "{{(\s?cookiecutter)[.](.*?)}}"
|
||||
PATTERN = r"{{(\s?cookiecutter)[.](.*?)}}"
|
||||
RE_OBJ = re.compile(PATTERN)
|
||||
|
||||
YN_CHOICES = ["y", "n"]
|
||||
CLOUD_CHOICES = ["AWS", "GCE"]
|
||||
CLOUD_CHOICES = ["AWS", "GCE", "None"]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
|
@ -17,7 +17,7 @@ defaultEntryPoints = ["http", "https"]
|
|||
[acme]
|
||||
# Email address used for registration
|
||||
email = "{{ cookiecutter.email }}"
|
||||
storageFile = "/etc/traefik/acme/acme.json"
|
||||
storage = "/etc/traefik/acme/acme.json"
|
||||
entryPoint = "https"
|
||||
onDemand = false
|
||||
OnHostRule = true
|
||||
|
|
|
@ -266,10 +266,10 @@ CELERY_TASK_SERIALIZER = "json"
|
|||
CELERY_RESULT_SERIALIZER = "json"
|
||||
# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-time-limit
|
||||
# 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
|
||||
# TODO: set to whatever value is adequate in your circumstances
|
||||
CELERYD_TASK_SOFT_TIME_LIMIT = 60
|
||||
CELERY_TASK_SOFT_TIME_LIMIT = 60
|
||||
|
||||
{%- endif %}
|
||||
# django-allauth
|
||||
|
|
|
@ -66,10 +66,12 @@ SECURE_CONTENT_TYPE_NOSNIFF = env.bool(
|
|||
"DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True
|
||||
)
|
||||
|
||||
{% if cookiecutter.cloud_provider != 'None' -%}
|
||||
# STORAGES
|
||||
# ------------------------------------------------------------------------------
|
||||
# https://django-storages.readthedocs.io/en/latest/#installation
|
||||
INSTALLED_APPS += ["storages"] # noqa F405
|
||||
{%- endif -%}
|
||||
{% if cookiecutter.cloud_provider == 'AWS' %}
|
||||
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
|
||||
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"
|
||||
GS_BUCKET_NAME = env("DJANGO_GCE_STORAGE_BUCKET_NAME")
|
||||
GS_DEFAULT_ACL = "publicRead"
|
||||
{% endif %}
|
||||
{% endif -%}
|
||||
|
||||
{% if cookiecutter.cloud_provider != 'None' or cookiecutter.use_whitenoise == 'y' -%}
|
||||
# STATIC
|
||||
# ------------------------
|
||||
{% endif -%}
|
||||
{% if cookiecutter.use_whitenoise == 'y' -%}
|
||||
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
|
||||
{%- endif -%}
|
||||
{%- if cookiecutter.cloud_provider == 'AWS' %}
|
||||
{% elif cookiecutter.cloud_provider == 'AWS' -%}
|
||||
STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage"
|
||||
STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/static/"
|
||||
{%- elif cookiecutter.cloud_provider == 'GCE' %}
|
||||
STATIC_URL = "https://storage.googleapis.com/{}/static/".format(GS_BUCKET_NAME)
|
||||
{%- endif %}
|
||||
{% elif cookiecutter.cloud_provider == 'GCE' -%}
|
||||
STATIC_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/static/"
|
||||
{% endif -%}
|
||||
|
||||
# MEDIA
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -117,6 +120,7 @@ from storages.backends.s3boto3 import S3Boto3Storage # noqa E402
|
|||
|
||||
class StaticRootS3Boto3Storage(S3Boto3Storage):
|
||||
location = "static"
|
||||
default_acl = "public-read"
|
||||
|
||||
|
||||
class MediaRootS3Boto3Storage(S3Boto3Storage):
|
||||
|
@ -128,8 +132,8 @@ class MediaRootS3Boto3Storage(S3Boto3Storage):
|
|||
DEFAULT_FILE_STORAGE = "config.settings.production.MediaRootS3Boto3Storage"
|
||||
MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/media/"
|
||||
{%- elif cookiecutter.cloud_provider == 'GCE' %}
|
||||
MEDIA_URL = "https://storage.googleapis.com/{}/media/".format(GS_BUCKET_NAME)
|
||||
MEDIA_ROOT = "https://storage.googleapis.com/{}/media/".format(GS_BUCKET_NAME)
|
||||
MEDIA_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/media/"
|
||||
MEDIA_ROOT = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/media/"
|
||||
{%- endif %}
|
||||
|
||||
# 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
|
||||
COMPRESS_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
|
||||
# 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 %}
|
||||
{%- if cookiecutter.use_whitenoise == 'n' -%}
|
||||
# Collectfast
|
||||
|
@ -288,7 +292,7 @@ SENTRY_LOG_LEVEL = env.int("DJANGO_SENTRY_LOG_LEVEL", logging.INFO)
|
|||
|
||||
sentry_logging = LoggingIntegration(
|
||||
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' %}
|
||||
|
|
|
@ -45,7 +45,7 @@ services:
|
|||
{%- if cookiecutter.use_celery == 'y' %}
|
||||
|
||||
redis:
|
||||
image: redis:3.2
|
||||
image: redis:5.0
|
||||
|
||||
celeryworker:
|
||||
<<: *django
|
||||
|
|
|
@ -44,7 +44,7 @@ services:
|
|||
- "0.0.0.0:443:443"
|
||||
|
||||
redis:
|
||||
image: redis:3.2
|
||||
image: redis:5.0
|
||||
{%- if cookiecutter.use_celery == 'y' %}
|
||||
|
||||
celeryworker:
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
-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
|
||||
Sphinx==2.0.1 # https://github.com/sphinx-doc/sphinx
|
||||
{%- 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 %}
|
||||
psycopg2-binary==2.8.2 # https://github.com/psycopg/psycopg2
|
||||
{%- endif %}
|
||||
|
@ -17,7 +17,7 @@ pytest-sugar==0.9.2 # https://github.com/Frozenball/pytest-sugar
|
|||
|
||||
# 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
|
||||
black==19.3b0 # https://github.com/ambv/black
|
||||
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
|
||||
|
||||
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
|
||||
pytest-django==3.4.8 # https://github.com/pytest-dev/pytest-django
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
-r ./base.txt
|
||||
|
||||
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' %}
|
||||
Collectfast==0.6.2 # https://github.com/antonagestam/collectfast
|
||||
{%- endif %}
|
||||
{%- 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 %}
|
||||
|
||||
# Django
|
||||
|
@ -18,4 +18,4 @@ django-storages[boto3]==1.7.1 # https://github.com/jschneier/django-storages
|
|||
{%- elif cookiecutter.cloud_provider == 'GCE' %}
|
||||
django-storages[google]==1.7.1 # https://github.com/jschneier/django-storages
|
||||
{%- 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"
|
||||
|
||||
|
||||
def test_list():
|
||||
assert reverse("users:list") == "/users/"
|
||||
assert resolve("/users/").view_name == "users:list"
|
||||
|
||||
|
||||
def test_update():
|
||||
assert reverse("users:update") == "/users/~update/"
|
||||
assert resolve("/users/~update/").view_name == "users:update"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from django.urls import path
|
||||
|
||||
from {{ cookiecutter.project_slug }}.users.views import (
|
||||
user_list_view,
|
||||
user_redirect_view,
|
||||
user_update_view,
|
||||
user_detail_view,
|
||||
|
@ -9,7 +8,6 @@ from {{ cookiecutter.project_slug }}.users.views import (
|
|||
|
||||
app_name = "users"
|
||||
urlpatterns = [
|
||||
path("", view=user_list_view, name="list"),
|
||||
path("~redirect/", view=user_redirect_view, name="redirect"),
|
||||
path("~update/", view=user_update_view, name="update"),
|
||||
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.mixins import LoginRequiredMixin
|
||||
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()
|
||||
|
||||
|
@ -16,16 +16,6 @@ class UserDetailView(LoginRequiredMixin, DetailView):
|
|||
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):
|
||||
|
||||
model = User
|
||||
|
|
Loading…
Reference in New Issue
Block a user