skip to content

Projects & Settings

A Django project is settings plus installed apps, driven by manage.py commands and system checks and upgraded release by release. Interviewers probe how a request travels through it.

part ofDjangooverview, primer and where to startread it →
on this pageshow

explore

questions

30

In Django, what is the difference between a project and an app, and what do startproject and startapp each create?

level: juniorimportance: must knowfreq 70%

answer

  1. one settings module versus many packages
  2. configuration versus features
  3. wired in through INSTALLED_APPS
  4. manage.py, settings, urls, wsgi, asgi

basics

~20 s

A Django project is the configured site: a settings module, a root URLconf and the WSGI/ASGI entry points. An app is a Python package providing one set of features, enabled by listing it in INSTALLED_APPS; one project combines many apps.

solid answer

~40 s

The **project** is the whole configured web application. `django-admin startproject clinic` creates `manage.py` and a `clinic` package with `settings.py`, `urls.py`, `asgi.py` and `wsgi.py`. An **app** is a Python package that provides one set of features — models, views, templates, static files, admin registrations. `python manage.py startapp scheduling` creates `__init__.py`, `admin.py`, `apps.py`, `migrations/`, `models.py`, `tests.py` and `views.py`. An app does nothing until the project lists it in `INSTALLED_APPS` and, for URLs, includes its URLconf. A project holds many apps, an app can be installed in many projects, and Django's docs note there is no `Application` object: the registry keeps an `AppConfig` per installed app.

go deeper

for a junior

Define project as the configured site and app as a feature package, and list what startproject and startapp generate.

for a middle

Explain that INSTALLED_APPS turns a package into an app, that the registry keeps one AppConfig per app, and that apps share one process and settings.

for a senior

Judge when code deserves its own app versus a module inside an existing one, keeping models, migrations and admin cohesive per app.

for a principal

Frame apps as the unit of ownership and reuse across teams, and weigh the migration cost of getting boundaries wrong early.

## Two different units Django separates **configuration** from **features**. The **project** is the configured site; an **app** is a reusable bundle of features the project switches on. Getting this split right is the first design decision on any Django codebase, including a clinic-booking system with scheduling, patients and billing. ## What the project is Django's documentation says a project "is defined primarily by a settings module". Running `django-admin startproject clinic` produces: - `manage.py` — a thin wrapper that sets `DJANGO_SETTINGS_MODULE` and runs management commands; - `clinic/settings.py` — `INSTALLED_APPS`, `MIDDLEWARE`, `DATABASES`, `TEMPLATES` and the rest; - `clinic/urls.py` — the root URLconf that `ROOT_URLCONF` points at; - `clinic/wsgi.py` and `clinic/asgi.py` — the entry points servers import; - `clinic/__init__.py` — making it a package. The project package can also hold site-wide templates, fixtures or static files that belong to no single app. ## What an app is An **app** is "a Python package that provides some set of features". Running `python manage.py startapp scheduling` produces: | File | Purpose | |---|---| | `__init__.py` | makes the directory a package | | `apps.py` | an `AppConfig` subclass with `name = 'scheduling'` | | `models.py` | the app's models | | `migrations/` | the app's migration files | | `admin.py` | admin registrations | | `views.py` | the app's views | | `tests.py` | the app's tests | There is no `urls.py` in the generated app; you add one when the app serves URLs. Since Django 6.0 the generated `apps.py` no longer sets `default_auto_field`, because `DEFAULT_AUTO_FIELD` itself now defaults to `BigAutoField`. ## How the two connect 1. **`INSTALLED_APPS`** lists the app, either as a package path (`"scheduling"`) or as the dotted path to its config class (`"scheduling.apps.SchedulingConfig"`, which the settings reference calls preferred). 2. The **app registry** (`django.apps.apps`) creates one `AppConfig` per entry at startup, imports each app's models and then runs each `ready()`. 3. The root **URLconf** includes the app's URL patterns, if it has any. 4. Other mechanisms — `MIDDLEWARE`, template inheritance — can also pull app code in. The docs stress there is no `Application` object at runtime: an app is "a set of code that interacts with various parts of the framework", and `AppConfig` is only its metadata record. ## Common confusions - **"An app is a microservice."** No — all apps in a project share one process, one settings module and usually one database. - **"Every folder in the project is an app."** Only packages listed in `INSTALLED_APPS` are apps to Django; a `utils/` package is just Python. - **"The project package cannot have models."** It can, if you add it to `INSTALLED_APPS`, though keeping models in apps is the norm. - **"startapp registers the app."** It only creates files; the app is inactive until you add it to `INSTALLED_APPS`. ## A worked split for a clinic-booking site A clinic-booking project might look like this after the first week: ```text clinic/ # project root, contains manage.py manage.py clinic/ # project package: settings, root URLconf, entry points settings.py urls.py asgi.py wsgi.py accounts/ # app: custom user model patients/ # app: patient records scheduling/ # app: slots and appointments billing/ # app: invoices and payments ``` Each of `accounts`, `patients`, `scheduling` and `billing` is listed in `INSTALLED_APPS`, owns its own `migrations/` directory, and contributes URLs through an `include()` in `clinic/urls.py`. The `clinic` package itself stays small: configuration and wiring, not features. When a second clinic product later needs appointment scheduling, the `scheduling` app is the unit that could be extracted, which is exactly what the project/app split is for. ## What an interviewer is listening for A junior answer distinguishes the configured site from the feature packages and knows the files each command creates. A stronger answer explains that `INSTALLED_APPS` is what turns a package into an app, and that apps are the unit of reuse — which is why third-party packages such as Django's own `django.contrib.admin` are apps too.

  • What is the difference between django-admin startproject and python manage.py startapp?
    `startproject` runs before any project exists, so it is a `django-admin` command that creates `manage.py` and the settings package. `startapp` is usually run through `manage.py`, which already knows the settings module; it creates a new app package inside the project root. Neither command edits `INSTALLED_APPS` for you.
  • Can a project run with an app that has no models?
    Yes. An app is any package that provides features: it might contribute only template tags, management commands, static files or middleware. Listing it in `INSTALLED_APPS` is still what makes Django look for those resources in it, such as its `templates/` directory or its `management/commands/` modules.

A project is a clinic building with its wiring and front desk; apps are the departments. A department does nothing until the building lists it in the directory and gives it a door, which is what INSTALLED_APPS and the URLconf do.

saying these in an interview costs you the question

  • Calls each Django app a separate service with its own process
  • Believes startapp adds the app to INSTALLED_APPS automatically
  • Says a project can contain only one app
  • Treats any Python package in the repository as a Django app
  • Thinks the project package can never define models
open as a page

In Django, why must the runserver development server never serve production traffic, and what serves the application instead?

level: juniorimportance: must knowfreq 68%

basics

~10 s

runserver is a convenience server built on Python's wsgiref that Django never security-audited or performance-tested. Production serves the same WSGI or ASGI application object from wsgi.py or asgi.py through a dedicated application server.

open as a page

In Django, what does DEBUG=True change, and what must you also set once DEBUG is False in production?

level: juniorimportance: must knowfreq 72%

basics

~20 s

DEBUG=True shows detailed tracebacks with settings and local variables, records every SQL query per connection, and trusts localhost when ALLOWED_HOSTS is empty. With DEBUG=False you must set ALLOWED_HOSTS, or every request returns 400 Bad Request.

open as a page

Django calls itself an MTV framework rather than MVC, so what do its model, template and view do, and where is the controller?

level: juniorimportance: must knowfreq 72%

basics

~20 s

Django's model is the data layer, its view is the Python callable that decides which data a URL returns, and its template decides how that data looks. The framework itself, routing requests through the URLconf, plays MVC's controller.

open as a page

In Django, what is AppConfig.ready() for, and what should you avoid doing inside it?

level: middleimportance: must knowfreq 55%

basics

~20 s

AppConfig.ready() runs after every installed app's models are loaded, so it suits startup wiring such as importing signal receivers. Avoid database queries there: ready() runs on every management command and can run more than once in tests.

open as a page

How do you write and register a custom Django system check that verifies a third-party API key setting is present?

level: middleimportance: must knowfreq 50%

basics

~20 s

Write a function taking app_configs plus keyword arguments that returns a list of django.core.checks messages, such as Error(..., id="shipping.E001"), when the setting is missing; decorate it with @register and import its module from AppConfig.ready() so it registers.

open as a page

What does Django's manage.py check --deploy add, and how do you make it fail a CI build on deployment warnings?

level: middleimportance: must knowfreq 55%

basics

~20 s

check --deploy adds checks registered with deploy=True, mostly security.* warnings such as W004, W018 and W020. They are warnings, so the default exit status stays 0; run it with production settings and --fail-level WARNING to fail CI.

open as a page

How do you write a custom Django management command, such as a nightly job that deactivates expired coupons in a shop app?

level: middleimportance: must knowfreq 62%

basics

~10 s

Create shop/management/commands/expire_coupons.py defining Command(BaseCommand): declare options in add_arguments(parser), do the work in handle() using the parsed options, write through self.stdout with self.style, and raise CommandError on failure.

open as a page

How do you give a Django project different settings for development, staging and production, and how does Django decide which settings module to load?

level: middleimportance: must knowfreq 60%

basics

~20 s

Django loads the settings module named by the DJANGO_SETTINGS_MODULE environment variable, or a command's --settings option. Per-environment setups use a shared base module with small dev, staging and prod modules, or one module reading environment variables, with secrets always from the environment.

open as a page

In Django, what happens, in order, between WSGIHandler receiving a request for /recipes/42/ and the HttpResponse going back to the server?

level: middleimportance: must knowfreq 62%

basics

~10 s

WSGIHandler builds an HttpRequest and passes it down the MIDDLEWARE chain; innermost, the resolver matches the path against ROOT_URLCONF and the view returns an HttpResponse, which travels back up the middleware in reverse order.

open as a page

How does Django's deprecation policy decide when a deprecated API is removed, and how do you surface those warnings in your project?

level: middleimportance: must knowfreq 55%

basics

~20 s

An API deprecated in release A.x keeps working with a RemovedInDjangoXYWarning and is removed in B.0, or B.1 if deprecated in the X.2 LTS, so shims last two feature releases. Surface them with python -Wa manage.py test.

open as a page

How would you upgrade a Django CRM from 4.2 LTS to 5.2 LTS with the least risk?

level: seniorimportance: must knowfreq 60%

basics

~20 s

Move Python into the range both support (3.10-3.12), take the latest 4.2 patch, fix every Django deprecation warning under python -Wa, upgrade dependencies, then step 5.0, 5.1, 5.2 on their latest patches, running the full suite at each step.

open as a page

What is Django's system check framework, and when do its checks run without anyone calling manage.py check?

level: juniorimportance: should knowfreq 45%

basics

~20 s

Django's system check framework (django.core.checks) is a registry of static validations over models, settings, URLs and templates. Besides manage.py check, it runs before most management commands, including runserver and migrate, but never inside the deployed request path.

open as a page

In Django, what is the difference between the django-admin utility and a project's manage.py, and when do you use each?

level: juniorimportance: should knowfreq 48%

basics

~10 s

Both run the same command machinery. manage.py is generated per project and sets DJANGO_SETTINGS_MODULE to that project's settings; django-admin is installed with Django and needs settings supplied, so it suits startproject and switching settings.

open as a page

In a Django app, what is each of models.py, views.py, urls.py, admin.py, apps.py and tests.py for, and which does Django find by convention?

level: juniorimportance: should knowfreq 48%

basics

~10 s

models.py holds models, views.py view callables, urls.py URL patterns, admin.py admin registrations, apps.py the AppConfig, tests.py tests. Django finds models, apps, admin and test*.py modules by name; views and urls run only when referenced.

open as a page

How does Django number and schedule its releases, and what makes an LTS release such as 5.2 different?

level: juniorimportance: should knowfreq 48%

basics

~20 s

Django ships a feature release (A.B) roughly every eight months and patch releases (A.B.C) as needed. Since 2.0, each X.2 release, such as 4.2 and 5.2, is long-term support: security and data-loss fixes for typically three years.

open as a page

Why does the order of INSTALLED_APPS matter in Django when two apps provide a template, static file or management command with the same name?

level: middleimportance: should knowfreq 42%

basics

~20 s

When several installed apps provide the same template, static file, management command or translation, the app listed first in INSTALLED_APPS takes precedence. To override django.contrib.admin's template from your own app, your app must come before the admin in the list.

open as a page

In Django's system check framework, how do message levels and ids like security.W004 work, and what does SILENCED_SYSTEM_CHECKS suppress?

level: middleimportance: should knowfreq 35%

basics

~20 s

Messages carry a level (Debug to Critical); Error and Critical stop management commands, lower levels are printed. Ids follow applabel.X001, where X marks the level. SILENCED_SYSTEM_CHECKS lists ids whose messages are hidden and excluded from the pass/fail decision.

open as a page

In Django, how do you run a management command from Python code with call_command(), and how does that differ from the command line?

level: middleimportance: should knowfreq 42%

basics

~10 s

call_command("expire_coupons", dry_run=True, stdout=buf) runs a command in-process. Keyword options bypass argparse and map to dest names, system checks are skipped by default, and CommandError propagates as an exception instead of exiting.

open as a page

In Django, why is django.conf.settings a lazy object, and when would you call settings.configure() instead of setting DJANGO_SETTINGS_MODULE?

level: middleimportance: should knowfreq 40%

basics

~20 s

django.conf.settings is a LazySettings proxy: importing it loads nothing, and the first attribute access imports the module named by DJANGO_SETTINGS_MODULE. settings.configure() supplies settings in code instead, for standalone use of Django components; call it once, before any setting is read.

open as a page

Why can't a team running Django 5.2 on Python 3.11 simply upgrade to Django 6.1, and in what order should they upgrade?

level: middleimportance: should knowfreq 36%

basics

~20 s

Django 6.0 and 6.1 support only Python 3.12, 3.13 and 3.14; 5.2 is the last series supporting 3.10 and 3.11. Upgrade the interpreter to 3.12 or newer while still on 5.2, which supports it, then upgrade Django.

open as a page

A Django project fails at startup with AppRegistryNotReady: Apps aren't loaded yet. What typically causes it, and how do you fix it?

level: seniorimportance: should knowfreq 38%

basics

~20 s

AppRegistryNotReady means code needed the app registry before django.setup() finished: models imported from an app's init.py or apps.py, a script that skipped django.setup(), or non-lazy gettext at import time. Defer the import or call setup first.

open as a page

A custom Django system check that queries a shop table breaks migrate on a fresh database and every command in CI; what is wrong and how do you fix it?

level: seniorimportance: should knowfreq 26%

basics

~20 s

An untagged check runs before nearly every command, so its query fails wherever no database or table exists, and migrate runs checks before migrating. Keep data invariants out of checks; tag real database checks with Tags.database and use only the aliases passed in.

open as a page

A nightly Django management command that expires shop coupons catches every exception and writes it to self.stderr; why does cron never alert, and how would you harden it?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Catching every exception lets handle() return normally, so the process exits 0 and cron sees success. Raise CommandError or let exceptions propagate for a non-zero status, and make the work idempotent so a re-run finishes what a partial run left.

open as a page

In Django code, why is copying a setting into a module-level constant or default argument at import time a bug, and what should you do instead?

level: seniorimportance: should knowfreq 33%

basics

~20 s

A module-level TAX_RATE = settings.PAYROLL_TAX_RATE or a default argument freezes the value when the module is imported: test overrides cannot reach it, and importing the module before settings exist fails. Read settings inside functions at call time instead.

open as a page

In a Django site served by several worker processes, which parts of the request path are built once per process rather than per request, and what bugs follow?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Settings, the app registry, the handler with its middleware instances and the cached URL resolver are built once per process. Request state stored on middleware instances, or values computed at import time, therefore leaks between requests or goes stale.

open as a page

When splitting a Django clinic-booking monolith into apps, how do you decide the boundaries, and when should an app become reusable?

level: principalimportance: should knowfreq 24%

basics

~20 s

Draw Django app boundaries around cohesive domain areas whose models change together, keep cross-app dependencies one-directional, and decide early because labels and migrations make moving models costly. Make an app reusable only when a second project needs it.

open as a page

What Django upgrade cadence would you set for a team's services: LTS-to-LTS jumps, or following every feature release, and why?

level: principalimportance: should knowfreq 30%

basics

~20 s

A trade-off: LTS-to-LTS means upgrading about every two years with three releases of change per jump; tracking feature releases means small steps every eight months and short support windows. A common middle path deploys the LTS and tests newer releases in CI.

open as a page

In Django, how does manage.py shell differ from manage.py dbshell, and what does shell import automatically since Django 5.2?

level: middleimportance: nice to knowfreq 30%

basics

~20 s

shell opens a Python interpreter with Django configured, so you use the ORM; dbshell launches the database's own SQL client with DATABASES credentials. Since 5.2 shell auto-imports every installed app's models, and since 6.0 also settings, connection and timezone.

open as a page

In Django, what are AppConfig.name and AppConfig.label, and why is changing an app's label after migrations have run risky?

level: seniorimportance: nice to knowfreq 26%

basics

~20 s

AppConfig.name is the app's full dotted Python path; AppConfig.label is its short identifier, defaulting to the last path component. The label is baked into default table names, migrations, content types and permissions, so changing it later breaks databases.

open as a page