Project Structure
Understand the structure of a Django project and how to organize apps within it.
50 min•By Priygop Team•Last updated: Feb 2026
Understanding Django Project Structure
Django projects have a specific structure that helps organize code and follows best practices for web development.
Project Layout
Example
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
Example
# 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")