Django de-structuring of URLs

Viewed 56

I am learning the Django Web Framework but just could not work my head around this logic. Let's say we have a Django App that has a very big urls.py where all the patterns are stored here. How would one go about splitting this into a urls folder, wherein it contains multiple 'urls.py' files? And not only that, to have a nested directory within the urls folder as well.

Example project structure of what I am thinking of:

>main_base
 >__init__.py
 >asgi.py
 >settings.py
 >wsgi.py
 >urls.py
>secondary_app
 >admin.py
 >apps.py
 >models.py
 >__init__.py
 >views
  >home.py
  >idea.py
  >project.py
  >business_partners
   >customers.py
   >vendors.py
 >urls
  >__init__.py
  >home.py
  >idea.py
  >project.py
  >business_partners
   >__init__.py
   >customers.py
   >vendors.py

in main_base/urls, I would have the following:

from django.urls import path, include

urlpatterns = [
    path('', include('secondary_app.urls')),
]

in secondary_app/urls/init.py, I would expect to do the following:

from django.urls import path, include

urlpatterns = [
    path('', include('secondary_app.urls.home')),
    path('', include('secondary_app.urls.idea')),
    path('', include('secondary_app.urls.project')),
    path('', include('secondary_app.urls.business_partners')),
]

And lastly in secondary_app/urls/business_partners/init.py, I would do the following:

from django.urls import path, include

urlpatterns = [
    path('', include('secondary_app.urls.business_partners.customers')),
    path('', include('secondary_app.urls.business_partners.vendors')),
]

I have tested it and it works all the way up till the secondary_app/urls directory level. But once I go one more level down, it throws a reverse match not found error. Example error:

NoReverseMatch at /
Reverse for 'bp-customers' with arguments '('',)' not found. 1 pattern(s) tried: ['bp/customers']

Any help is really really appreciated!

2 Answers

If you want your views in separate files do this (assuming CBV):

main_base/urls.py:

from django.urls import path, include

urlpatterns = [
    path('', include('secondary_app.urls')),
]

secondary_app/urls.py:

from django.urls import path
from .views.home import HomeViewName
from .views.idea import IdeaViewName

urlpatterns = [
    path('', HomeViewName.as_view(), name='home'),
    path('idea/', IdeaViewName.as_view(), name='idea'),
    ### other views
]

This way your views will be in separate files and you will have routing to them

You should read official docs on django routing because it will answer your questions in greater detail.

When you create a django project with django-admin startproject myprojectand a app with django-admin startapp myapp the default django project layout is like:

-basedir/
--myproject
---asgi.py
---__init__.py
---__pycache_/
---settings.py
---urls.py
---wsgi.py
--myapp
---migrations/
---admin.py
---apps.py
---__init__.py
---models.py
---tests.py
---views.py
---manage.py

Base project directory and also every django app comes with urls.py file.There is a couple benefits for this structure but mainly keeps all related urls in it's own appdir to keep maintenance easier. Than you can include your apps urls in myproject/urls.py. For example :

in myproject/urls.py

from django.urls import path, include
urlpatterns = [
    path('', include('myapp.urls')),
]

But if you would like to change the layout of a django project you can try

basedir/
--root_configuration/
--root_apps/

to keep your project files in one file and all the django apps in one file

Related