Project Structure
Understand the structure of a Django project and how to organize apps within it. This is a foundational concept in Python web development that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world Python/Django experience. Take your time with each section and practice the examples
Understanding Django Project Structure
Django projects have a specific structure that helps organize code and follows best practices for web development.. This is an essential concept that every Python/Django developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Project Layout
myproject/
├── manage.py # Django's command-line utility
├── myproject/ # Project configuration directory
│ ├── __init__.py
│ ├── settings.py # Project settings
│ ├── urls.py # URL declarations
│ ├── asgi.py # ASGI config
│ └── wsgi.py # WSGI config
└── apps/ # Application directory (custom)
└── blog/ # Example app
├── __init__.py
├── admin.py # Admin interface
├── apps.py # App configuration
├── models.py # Database models
├── tests.py # Unit tests
├── urls.py # App URL patterns
└── views.py # View functions
# Create a new app
python manage.py startapp blog
# Add app to INSTALLED_APPS in settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', # Add your app here
]Practice Exercise: App Generator
# Django App Generator
import os
import re
class DjangoAppGenerator:
def __init__(self, project_root):
self.project_root = project_root
self.apps_dir = os.path.join(project_root, 'apps')
# Create apps directory if it doesn't exist
if not os.path.exists(self.apps_dir):
os.makedirs(self.apps_dir)
def create_app(self, app_name):
"""Create a new Django app with proper structure"""
app_path = os.path.join(self.apps_dir, app_name)
if os.path.exists(app_path):
print(f"App {app_name} already exists!")
return False
# Create app directory
os.makedirs(app_path)
# Create __init__.py
with open(os.path.join(app_path, '__init__.py'), 'w') as f:
f.write("# Django app initialization\n")
# Create apps.py
apps_content = f'''from django.apps import AppConfig
class {app_name.capitalize()}Config(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.{app_name}'
verbose_name = '{app_name.replace("_", " ").title()}'
'''
with open(os.path.join(app_path, 'apps.py'), 'w') as f:
f.write(apps_content)
# Create models.py
models_content = '''from django.db import models
# Define your models here
class ExampleModel(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Meta:
verbose_name = "Example Model"
verbose_name_plural = "Example Models"
'''
with open(os.path.join(app_path, 'models.py'), 'w') as f:
f.write(models_content)
# Create views.py
views_content = '''from django.shortcuts import render
from django.http import HttpResponse
# Define your views here
def index(request):
return HttpResponse(f"Welcome to {app_name} app!")
def about(request):
return HttpResponse(f"This is the about page for {app_name} app.")
'''
with open(os.path.join(app_path, 'views.py'), 'w') as f:
f.write(views_content)
# Create urls.py
urls_content = f'''from django.urls import path
from . import views
app_name = '{app_name}'
urlpatterns = [
path('', views.index, name='index'),
path('about/', views.about, name='about'),
]
'''
with open(os.path.join(app_path, 'urls.py'), 'w') as f:
f.write(urls_content)
# Create admin.py
admin_content = f'''from django.contrib import admin
from .models import ExampleModel
@admin.register(ExampleModel)
class ExampleModelAdmin(admin.ModelAdmin):
list_display = ['name', 'created_at']
list_filter = ['created_at']
search_fields = ['name', 'description']
'''
with open(os.path.join(app_path, 'admin.py'), 'w') as f:
f.write(admin_content)
# Create tests.py
tests_content = f'''from django.test import TestCase
from .models import ExampleModel
class {app_name.capitalize()}ModelTests(TestCase):
def test_example_model_creation(self):
model = ExampleModel.objects.create(
name="Test Model",
description="Test Description"
)
self.assertEqual(model.name, "Test Model")
self.assertEqual(model.description, "Test Description")
'''
with open(os.path.join(app_path, 'tests.py'), 'w') as f:
f.write(tests_content)
print(f"App {app_name} created successfully in {app_path}")
return True
# Usage example
if __name__ == "__main__":
generator = DjangoAppGenerator(".")
generator.create_app("blog")
generator.create_app("users")