Django is a high-level Python web framework designed for rapid development and clean, pragmatic design. It follows the Model-Template-View (MTV) architectural pattern, which separates concerns by placing data structure in Models, presentation logic in Templates, and business logic in Views. Django ships with many built-in features out of the box, including an Object-Relational Mapper (ORM), an auto-generated admin interface, an authentication system, and a templating engine, making it a batteries-included framework for building web applications.
A Django project is created using the command django-admin startproject myproject, which generates the project directory containing several key files. The manage.py file is a thin wrapper around django-admin that sets the DJANGO_SETTINGS_MODULE to the project's settings.py and serves as the recommended entry point for project-level commands. The wsgi.py file exposes a WSGI-compatible callable used by production servers like Gunicorn or uWSGI for synchronous request handling, while asgi.py exposes an ASGI-compatible callable for servers like Daphne or Uvicorn, enabling async views, WebSockets, and long-lived connections through Django Channels. The settings.py file is the central configuration module containing settings such as INSTALLED_APPS, MIDDLEWARE, DATABASES, TEMPLATES, STATIC_URL, MEDIA_URL, ALLOWED_HOSTS, and SECRET_KEY.
Within a project, individual features are organized into apps, which are self-contained Python packages. An app is created with python manage.py startapp myapp and must be added to the INSTALLED_APPS list in settings.py to be registered with the project. Each app contains its own models.py, views.py, urls.py, admin.py, tests.py, and apps.py. The apps.py file holds the AppConfig subclass for the app, which can run startup code in its ready() method, such as registering signals. A project contains many apps, and a well-designed app can be reused across different projects by placing it on the PYTHONPATH and including it in INSTALLED_APPS. The root URL configuration in the project's urls.py typically delegates to app-level urls.py files using the include() function.