diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index ba8ab53e62..708acb4a77 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -45,7 +45,7 @@ Others #. ``jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag 'now'.``: please upgrade your cookiecutter version to >= 1.4 (see `#528`_) -#. New apps not getting created in project root: This is the expected behavior, because cookiecutter-django does not change the way that django startapp works, you'll have to fix this manually (see `#1725`_) +#. To create a new app using the recommended directory structure, run `django-admin startapp --template=../startapp_template myappname` from inside the project root. This template can be customized to suit your needs. (see `startapp`_) .. _#528: https://github.com/cookiecutter/cookiecutter-django/issues/528#issuecomment-212650373 -.. _#1725: https://github.com/cookiecutter/cookiecutter-django/issues/1725#issuecomment-407493176 +.. _startapp: https://docs.djangoproject.com/en/dev/ref/django-admin/#startapp diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 5655b61f94..d3113e24c1 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -111,6 +111,7 @@ def remove_celery_files(): os.path.join( "{{ cookiecutter.project_slug }}", "users", "tests", "test_tasks.py" ), + os.path.join("startapp_template", "tasks.py-tpl"), ] for file_name in file_names: os.remove(file_name) @@ -327,6 +328,9 @@ def remove_drf_starter_files(): "{{cookiecutter.project_slug}}", "users", "tests", "test_swagger.py" ) ) + shutil.rmtree(os.path.join("startapp_template", "api")) + os.remove(os.path.join("startapp_template", "tests", "test_drf_urls.py-tpl")) + os.remove(os.path.join("startapp_template", "tests", "test_drf_views.py-tpl")) def remove_storages_module(): diff --git a/{{cookiecutter.project_slug}}/startapp_template/__init__.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/__init__.py-tpl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/{{cookiecutter.project_slug}}/startapp_template/admin.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/admin.py-tpl new file mode 100644 index 0000000000..e56681f781 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/admin.py-tpl @@ -0,0 +1,4 @@ +"""Define and register {{ '{{' }} app_name {{ '}}' }} app admin models.""" +from django.contrib import admin + +# Register your models here. diff --git a/{{cookiecutter.project_slug}}/startapp_template/api/serializers.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/api/serializers.py-tpl new file mode 100644 index 0000000000..40c8ef03d2 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/api/serializers.py-tpl @@ -0,0 +1,2 @@ +"""Define serializers for the {{ '{{' }} app_name {{ '}}' }} api.""" +from rest_framework import serializers diff --git a/{{cookiecutter.project_slug}}/startapp_template/api/views.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/api/views.py-tpl new file mode 100644 index 0000000000..2077870b2e --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/api/views.py-tpl @@ -0,0 +1 @@ +"""Define API views for {{ '{{' }} app_name {{ '}}' }} app.""" diff --git a/{{cookiecutter.project_slug}}/startapp_template/apps.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/apps.py-tpl new file mode 100644 index 0000000000..12c0725ad1 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/apps.py-tpl @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class {{ '{{' }} camel_case_app_name {{ '}}' }}Config(AppConfig): + name = '{{ "{{" }} app_name {{ "}}" }}' diff --git a/{{cookiecutter.project_slug}}/startapp_template/forms.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/forms.py-tpl new file mode 100644 index 0000000000..1b2c3801f9 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/forms.py-tpl @@ -0,0 +1,4 @@ +"""Define {{ '{{' }} app_name {{ '}}' }} app forms.""" +from django.utils.translation import gettext_lazy as _ + +# Create your forms here. diff --git a/{{cookiecutter.project_slug}}/startapp_template/migrations/__init__.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/migrations/__init__.py-tpl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/{{cookiecutter.project_slug}}/startapp_template/models.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/models.py-tpl new file mode 100644 index 0000000000..c971bbcbc3 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/models.py-tpl @@ -0,0 +1,4 @@ +"""Define {{ '{{' }} app_name {{ '}}' }} app models.""" +from django.db import models + +# Create your models here. diff --git a/{{cookiecutter.project_slug}}/startapp_template/tasks.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tasks.py-tpl new file mode 100644 index 0000000000..8174f8b0ef --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/tasks.py-tpl @@ -0,0 +1,2 @@ +"""Define {{ '{{' }} app_name {{ '}}' }} app Celery tasks.""" +from config import celery_app diff --git a/{{cookiecutter.project_slug}}/startapp_template/tests/__init__.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tests/__init__.py-tpl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/{{cookiecutter.project_slug}}/startapp_template/tests/factories.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tests/factories.py-tpl new file mode 100644 index 0000000000..86c4c6a70a --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/tests/factories.py-tpl @@ -0,0 +1,5 @@ +"""Define factories to generate testing data.""" +from typing import Any, Sequence + +from factory import Faker, post_generation +from factory.django import DjangoModelFactory diff --git a/{{cookiecutter.project_slug}}/startapp_template/tests/test_admin.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tests/test_admin.py-tpl new file mode 100644 index 0000000000..875dbf7886 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/tests/test_admin.py-tpl @@ -0,0 +1,4 @@ +import pytest +from django.urls import reverse + +pytestmark = pytest.mark.django_db diff --git a/{{cookiecutter.project_slug}}/startapp_template/tests/test_drf_urls.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tests/test_drf_urls.py-tpl new file mode 100644 index 0000000000..2d5b56ed77 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/tests/test_drf_urls.py-tpl @@ -0,0 +1,4 @@ +import pytest +from django.urls import resolve, reverse + +pytestmark = pytest.mark.django_db diff --git a/{{cookiecutter.project_slug}}/startapp_template/tests/test_drf_views.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tests/test_drf_views.py-tpl new file mode 100644 index 0000000000..e2fb3849f3 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/tests/test_drf_views.py-tpl @@ -0,0 +1,4 @@ +import pytest +from django.test import RequestFactory + +pytestmark = pytest.mark.django_db diff --git a/{{cookiecutter.project_slug}}/startapp_template/tests/test_forms.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tests/test_forms.py-tpl new file mode 100644 index 0000000000..0344d53235 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/tests/test_forms.py-tpl @@ -0,0 +1,7 @@ +""" +Module for all {{ '{{' }} app_name {{ '}}' }} Form Tests. +""" +import pytest +from django.utils.translation import gettext_lazy as _ + +pytestmark = pytest.mark.django_db diff --git a/{{cookiecutter.project_slug}}/startapp_template/tests/test_models.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tests/test_models.py-tpl new file mode 100644 index 0000000000..a7057c2cc3 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/tests/test_models.py-tpl @@ -0,0 +1,3 @@ +import pytest + +pytestmark = pytest.mark.django_db diff --git a/{{cookiecutter.project_slug}}/startapp_template/tests/test_urls.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tests/test_urls.py-tpl new file mode 100644 index 0000000000..2d5b56ed77 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/tests/test_urls.py-tpl @@ -0,0 +1,4 @@ +import pytest +from django.urls import resolve, reverse + +pytestmark = pytest.mark.django_db diff --git a/{{cookiecutter.project_slug}}/startapp_template/tests/test_views.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/tests/test_views.py-tpl new file mode 100644 index 0000000000..b0f53c2358 --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/tests/test_views.py-tpl @@ -0,0 +1,11 @@ +import pytest +from django.conf import settings +from django.contrib import messages +from django.contrib.auth.models import AnonymousUser +from django.contrib.messages.middleware import MessageMiddleware +from django.contrib.sessions.middleware import SessionMiddleware +from django.http import HttpRequest +from django.test import RequestFactory +from django.urls import reverse + +pytestmark = pytest.mark.django_db diff --git a/{{cookiecutter.project_slug}}/startapp_template/views.py-tpl b/{{cookiecutter.project_slug}}/startapp_template/views.py-tpl new file mode 100644 index 0000000000..1d8ccb464c --- /dev/null +++ b/{{cookiecutter.project_slug}}/startapp_template/views.py-tpl @@ -0,0 +1,4 @@ +"""Define {{ '{{' }} app_name {{ '}}' }} app views.""" +from django.shortcuts import render + +# Create your views here.