[PYTHON] [Django] Directory structure practices + notes

Django application directory

The Django application creates a directory for each app, so If you add apps with $ python manage.py startapp hoge, folders will be created more and more in the root directory.

It's nice to be able to separate features for each directory, but not all features are in parallel, so the visibility gets worse as more applications are added.

In my case, I often nest directories as ./app/sub_app/... to make them cleaner.

--Example of creating applications in parallel Although the functions can be separated, it does not correspond to the url and the outlook is poor.

.
├── account/     (/account/login etc)
├── auth_api/    (/api/auth/...)
├── config
│   └── settings.py
├── email/       (/account/email/...)
├── manage.py
├── password/    (/account/password/...)
└── polls_api/   (/api/polls/...)

--Example of nesting applications The url and directory correspond and are easy to understand.

.
├── account/      (/account/login etc)
│   ├── email/    (/account/email/...)
│   └── password/ (/account/password/...)
├── api/
│   ├── auth/     (/api/auth/...)
│   └── polls/    (/api/polls/...)
├── config
│   └── settings.py
└── manage.py

However, there are many points to stumble, so I will summarize the points to note.

environment

Premise

The following is the folder structure when python manage.py startapp account is set after $ django-admin startproject config ..

.
├── account
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── config
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── poetry.lock
└── pyproject.toml

--Create urls.py

ʻUrls.py is often created in the application directory, so add ʻaccount / urls.py. Suppose you create a View called TopView.

account/urls.py


from django.urls import path, include
from . import views

app_name = 'account'
urlpatterns = [
    path("top/", views.TopView.as_view(), name="top")
]

Include ʻaccount / urls.py in config / urls.py`.

config/urls.py



from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('account/', include('account.urls')), #add to
]

--Register in settings.py Finally, enter the ʻaccount application in config / settings.py`.

config/settings.py


INSTALLED_APPS = [
    # defaults
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    #add to
    'account'
]

--URL reference

In this case, the TopView url is / account / top. In template, specify url as follows.

<a href="{% url 'account:top'%}">Link to top page</a>

When the HTML is rendered, Django expands it like this:

<a href="/account/top">Link to top page</a>

Create an application in the account directory

Create app

In the ʻaccount folder, create a passwordapp that summarizes password-related functions. It seems to be created bypython manage.py startapp password account / password`, Unfortunately, when I specify the location with startapp, it doesn't create a directory.

$ python manage.py startapp password account/password
CommandError: Destination directory '.../account/password' does not exist, please create it first.

You will be asked to create a directory first, so create it. Then, the app will be created in ʻaccount / password`.

$ mkdir account/password
$ python manage.py startapp password account/password

Current directory.

.
├── account
│   ├── (Abbreviation)
│   └── password
│        ├── __init__.py
│        ├── admin.py
│        ├── apps.py
│        ├── migrations
│        │   └── __init__.py
│        ├── models.py
│        ├── tests.py
│        └── views.py
├── config
│   └── (Abbreviation)
├── manage.py
├── poetry.lock
└── pyproject.toml

Register url

Create ʻaccount / password / urls.pyas before. I created a View calledPassChangeView` in View.

account/password/urls.py


from django.urls import path, include
from . import views

app_name = 'password'
urlpatterns = [
    path('change/', views.PassChangeView.as_view(), name='change'),
]

Include ʻurls.py in ʻaccount / urls.py.

At this time, if you include password.urls, it seems to work, but be careful because it will not work unless you set ʻaccount.password.urls`.

account/urls.py


from django.urls import path, include
from . import views

app_name = 'account'
urlpatterns = [
    path("top/", views.TopView.as_view(), name="top"),
    path("password/", include('account.password.urls'), name="password") #add to
]

At this time, the url of PassChangeView is / account / password / change.

url reference

In template, specify url as follows.

<a href="{% url 'account:password:change'%}">Link to top page</a>

Register the application in settings.py

ʻThe password was created in account / password, but migration is not possible unless the application is entered in config / settings.py. When filling in ʻINSTALLED_APPS, use **. ** instead of **: **.

config/settings.py


INSTALLED_APPS = [
    # defaults
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'account',
    'account.password' #add to
]

migrate

Note that the behavior is slightly different when migrating the password application.

$ python manage.py makemigrations password
    -> 〇
$ python manage.py makemigrations account.password
    -> ×
$ python manage.py makemigrations account:password
    -> ×
$ python manage.py makemigrations account/password
    -> ×

Summary

It is easier to understand the directory structure that corresponds to the path to some extent, but at first I stumbled in various places, so I summarized it. If you do up to 3 levels, it will be quite messy, but if you use 2 levels, it will be refreshing, so it is recommended.

Recommended Posts

[Django] Directory structure practices + notes
django notes
Django notes
Current directory structure
[Django] as_view () notes
Linux directory structure
Linux directory structure
Django Template notes
[Django] JWT notes
Celery notes on Django
[Personal notes] Python, Django
[Django] Notes on using django-debug-toolbar
Output table structure in Django