بنقرة واحدة
url-patterns
Django URL configuration patterns, namespaces, and nested structure conventions
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Django URL configuration patterns, namespaces, and nested structure conventions
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Best practices for writing Django tests (updated template)
GlueFetchHelper patterns for making AJAX calls in templates
Advanced seeding patterns for linking specific foreign keys
Apply DjangoSpire app CSS variables in templates instead of inline styles
Best practices for AI bots, prompts, and intel in scope_of_work
Examples on how we build our form views.
| name | url-patterns |
| description | Django URL configuration patterns, namespaces, and nested structure conventions |
This skill documents the URL configuration patterns, namespace conventions, and nested URL structure used throughout the Django Spire project. URLs are organized hierarchically to create readable "sentence-like" paths that clearly express their purpose.
company user page list)<uuid:company_slug>/The project uses a hierarchical URL structure:
system/urls.py (root)
├── django/admin/
├── django_glue/
├── django_spire/
├── theme/
└── <uuid:company_slug>/ (company-scoped base)
├── home/
├── catalog/
├── company/
├── inventory/
└── user_profile/
Each app contains only the URL type sub-namespaces it needs:
Important: Only create URL type namespaces when you have actual views to support them.
DO:
page/ namespace only if you have page views (list, detail, etc.)form/ namespace only if you have form views (create, update, delete)json/ namespace only if you have JSON API endpointsfile/ namespace only if you have file upload/download viewstemplate/ namespace only if you have template-based viewsredirect/ namespace only if you have redirect viewsDON'T:
Examples from the codebase:
page/ (no form, json, template, file needed)page/, form/, and nested user/ (no json, template, file needed)redirect/, json/, template/ (no page, form, file needed)page/, form/, template/ based on its view structureURLs are read as sentences by chaining namespaces:
<company_slug>/company/user/page/list/
↓ ↓ ↓ ↓ ↓
company → user → page → list
This creates the sentence: "company user page list"
urls/__init__.py - identifies the app{namespace}:{app_name}:{sub_namespace}:{view_name}app/your_app/
├── urls/
│ ├── __init__.py
│ └── {type}_urls.py (only create types you need)
├── views/
│ ├── __init__.py
│ └── {type}_views.py (only create types you need)
Note: Only create URL type files (page_urls.py, form_urls.py, etc.) when you have corresponding views. Don't create placeholder files for types you don't need.
Only include URL types that you need:
from __future__ import annotations
from django.urls.conf import include, path
app_name = 'your_app'
# Only include the types you actually have views for
urlpatterns = [
path('form/', include('app.your_app.urls.form_urls', namespace='form')),
path('page/', include('app.your_app.urls.page_urls', namespace='page')),
]
from __future__ import annotations
from django.urls import path
from app.your_app.views import page_views
app_name = 'page'
urlpatterns = [
path('list/', page_views.list_view, name='list'),
path('<int:pk>/detail/', page_views.detail_view, name='detail'),
]
from __future__ import annotations
from django.urls import path
from app.your_app.views import form_views
app_name = 'form'
urlpatterns = [
path('create/', form_views.create_view, name='create'),
path('<int:pk>/delete/', form_views.delete_view, name='delete'),
path('<int:pk>/update/', form_views.update_view, name='update'),
path('create/modal/', form_views.create_modal_view, name='create_modal'),
path('<int:pk>/delete/modal/', form_views.delete_modal_view, name='delete_modal'),
path('<int:pk>/update/modal/', form_views.update_modal_view, name='update_modal'),
]
from __future__ import annotations
from django.urls import path
from app.your_app.views import redirect_views
app_name = 'redirect'
urlpatterns = [
path('login/', redirect_views.login_redirect_view, name='login'),
path('callback/', redirect_views.callback_view, name='callback'),
]
In system/urls.py:
urlpatterns += [
path('<uuid:company_slug>/', include('app.your_app.urls', namespace='your_app')),
]
If your app contains sub-modules (e.g., location/field/, location/bin/), you must register the sub-module URLs in the parent app's urls/__init__.py:
# app/location/urls/__init__.py
from __future__ import annotations
from django.urls.conf import include, path
app_name = 'location'
urlpatterns = [
path('page/', include('app.location.urls.page_urls', namespace='page')),
path('form/', include('app.location.urls.form_urls', namespace='form')),
path('field/', include('app.location.field.urls', namespace='field')),
path('bin/', include('app.location.bin.urls', namespace='bin')),
path('warehouse/', include('app.location.warehouse.urls', namespace='warehouse')),
path('template/', include('app.location.urls.template_urls', namespace='template')),
path('json/', include('app.location.urls.json_urls', namespace='json')),
]
Important: Verify sub-module URLs are registered before using them in templates. Unregistered namespaces will result in empty string when using {% url %} in templates.
Before wiring a URL to a button or template, verify it exists:
DON'T:
<!-- ❌ DON'T: Assume URL exists without verification -->
{% url 'location:field:form:create' as field_create_url %}
{% include 'django_spire/button/secondary_outlined_button.html' with button_icon='bi bi-plus-lg' button_href=field_create_url %}
DO:
# ✅ DO: First verify the URL resolves correctly
# In Django shell or test:
>>> from django.urls import reverse
>>> reverse('location:field:form:create')
'/location/field/form/create/'
# If it raises NoReverseMatch, the URL isn't registered - check:
# 1. Parent app's urls/__init__.py includes the sub-module URLs
# 2. Sub-module's urls/__init__.py defines app_name correctly
# 3. URL name matches the namespace:app_name:view_name pattern
<!-- ✅ DO: Only add URL to template after verification -->
{% url 'location:field:form:create' as field_create_url %}
{% include 'django_spire/button/secondary_outlined_button.html' with button_icon='bi bi-plus-lg' button_href=field_create_url %}
from django.urls import reverse
# Full URL name with all namespaces
url_name = 'company:your_app:page:list'
# Reverse the URL
url = reverse(url_name, kwargs={'company_slug': company.uuid})
For deeper nesting (e.g., catalog/page/entry/):
# app/catalog/urls/__init__.py
from __future__ import annotations
from django.urls.conf import include, path
app_name = 'catalog'
urlpatterns = [
path('entry/', include('app.catalog.urls.entry_urls', namespace='entry')),
path('form/', include('app.catalog.urls.form_urls', namespace='form')),
path('page/', include('app.catalog.urls.page_urls', namespace='page')),
]
# app/catalog/urls/entry_urls.py
from __future__ import annotations
from django.urls.conf import include, path
app_name = 'entry'
urlpatterns = [
path('page/', include('app.catalog.urls.entry.page_urls', namespace='page')),
path('form/', include('app.catalog.urls.entry.form_urls', namespace='form')),
]
# ❌ DON'T: Sub-module URLs not registered in parent app
# app/location/urls/__init__.py
urlpatterns = [
path('page/', include('app.location.urls.page_urls', namespace='page')),
path('form/', include('app.location.urls.form_urls', namespace='form')),
# Missing: field, bin, warehouse sub-modules not included!
]
<!-- This will render href="" because the namespace doesn't exist -->
{% url 'location:field:form:create' as field_create_url %}
<a href="{{ field_create_url }}">Add Field</a>
<!-- Renders as: <a href="">Add Field</a> -->
# ✅ DO: All sub-module URLs properly registered
# app/location/urls/__init__.py
urlpatterns = [
path('page/', include('app.location.urls.page_urls', namespace='page')),
path('form/', include('app.location.urls.form_urls', namespace='form')),
path('field/', include('app.location.field.urls', namespace='field')),
path('bin/', include('app.location.bin.urls', namespace='bin')),
path('warehouse/', include('app.location.warehouse.urls', namespace='warehouse')),
]
<!-- Now this renders the correct href -->
{% url 'location:field:form:create' as field_create_url %}
{% include 'django_spire/button/secondary_outlined_button.html' with button_href=field_create_url %}
<!-- Renders as: <a href="/location/field/form/create/"> -->
# ❌ DON'T: All URLs in one file, hard to navigate
urlpatterns = [
path('list/', list_view, name='list'),
path('detail/<int:pk>/', detail_view, name='detail'),
path('create/', create_view, name='create'),
path('update/<int:pk>/', update_view, name='update'),
path('delete/<int:pk>/', delete_view, name='delete'),
]
# ✅ DO: Separated by type, clear organization
# urls/__init__.py
from __future__ import annotations
from django.urls.conf import include, path
urlpatterns = [
path('form/', include('app.your_app.urls.form_urls', namespace='form')),
path('page/', include('app.your_app.urls.page_urls', namespace='page')),
]
# urls/page_urls.py
from __future__ import annotations
from django.urls import path
from app.your_app.views import page_views
urlpatterns = [
path('list/', page_views.list_view, name='list'),
path('<int:pk>/detail/', page_views.detail_view, name='detail'),
]
# urls/form_urls.py
from __future__ import annotations
from django.urls import path
from app.your_app.views import form_views
urlpatterns = [
path('create/', form_views.create_view, name='create'),
path('<int:pk>/update/', form_views.update_view, name='update'),
]
# ❌ DON'T: Mixing patterns, unclear hierarchy
urlpatterns = [
path('list/', include('app.other.urls')), # No namespace
path('page/', include('app.other.urls')), # Inconsistent
]
# ✅ DO: Clear, consistent hierarchy
from __future__ import annotations
from django.urls.conf import include, path
urlpatterns = [
path('<uuid:company_slug>/', include('app.your_app.urls', namespace='your_app')),
]
# In app/your_app/urls/__init__.py
from __future__ import annotations
from django.urls.conf import include, path
urlpatterns = [
path('form/', include('app.your_app.urls.form_urls', namespace='form')),
path('page/', include('app.your_app.urls.page_urls', namespace='page')),
]
Full URL path: <company_slug>/company/user/page/list/
URL Chain:
system/urls.py: path('<uuid:company_slug>/', include('app.company.urls', namespace='company'))app/company/urls/__init__.py: path('user/', include('app.company.user.urls', namespace='user'))app/company/user/urls/__init__.py: path('page/', include('app.company.user.urls.page_urls', namespace='page'))app/company/user/urls/page_urls.py: path('list/', page_views.list_page_view, name='list')Reverse URL:
url = reverse('company:user:page:list', kwargs={'company_slug': company.uuid})
When reviewing URL configuration code, verify the following:
urls/ subdirectory with type-specific filesurls/__init__.py defines app_nameinclude() calls specify a namespace parameter{type}_urls.py naming conventionviews/ directory, not defined in URL files<int:pk>, <uuid:slug>, etc.)<uuid:company_slug>/ prefixlist, create, detail, update, delete)from __future__ import annotationsfrom django.urls.conf import include, path consistently