October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk4 min

I Built a Django Linter That Never Imports Django

A static checker can catch Django model fields declared but never migrated, without importing Django. Here is what it covers, what it does not, and when to use it.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A static checker can catch one dangerous kind of Django migration drift without starting Django at all: a model field that is declared in models.py but has never been added by a migration. The approach, described by FROWNINGdev in a DEV Community post, replays migration files into a field set and compares that set with the model declarations. It is useful when a cold CI runner or a broken virtual environment cannot run Django’s own commands. It does not replace Django’s migration machinery, and it does not check every migration behavior.

Why Django’s own check is the reference point

Django’s built-in answer to migration drift is python manage.py makemigrations --check. The command compares the current model state with the migrations on disk and exits with a non-zero status when model changes have no matching migration, which makes it a natural step in CI. The catch, as the author points out, is that it only works if the project’s dependencies are installed and its settings module imports cleanly. If either fails, the command never reaches the comparison.

As an Amazon Associate I earn from qualifying purchases.

The environments where that check cannot run

The motivating case is an environment where ordinary Django command execution cannot start. Two common examples:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Cold CI runners that execute a lint job before dependencies are installed, or that run it in a lightweight container with no database or secrets available to settings.
  • Broken virtual environments where a dependency has drifted, a settings module raises at import time, or a required environment variable is missing on a developer machine.

In both cases the check you actually want, whether a model field was ever migrated, is blocked by unrelated failures. A checker that reads source files sidesteps those failures because it never executes the project’s code.

How the static approach works

The technique rests on two representations of the same schema, both obtained without importing Django:

  1. Parse each migration file and replay its operations in order, such as field additions, removals and renames, into a reconstructed field set per model.
  2. Parse the model declarations in models.py to collect the fields each model declares.
  3. Diff the two sets. Any field declared in the models but absent from the replayed migration state is reported as drift.

Because both sides are read from source text, the checker needs only the files in the repository. The article does not list the parser or other libraries it depends on, so the exact install footprint of the tool is not established by the source.

What the checker detects, and what it does not

The article’s scope is narrow and should be read that way:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Detected: a field declared in a model but never added by any migration. This is the direction that causes runtime failures once code expects a column that the database does not have.
  • Not established: the reverse direction, where a migration adds or keeps a field that the model no longer declares. The source does not say whether this is covered.
  • Not claimed: full schema equivalence. Replaying operations into a field set does not verify database constraints, index definitions, data migrations, or the SQL that Django would generate for a given backend.
  • Not claimed: that the checker validates every migration’s behavior. It answers a question about declared fields, not about whether a migration runs correctly.

Treat it as an early warning in environments where Django’s check cannot run, not as a substitute for makemigrations --check in environments where it can.

Comparing the two approaches

Aspect makemigrations –check Static replay and model diff (as described)
Environment prerequisites Installed dependencies and a settings module that imports cleanly Repository files; no Django import, per the article
Drift direction detected Model changes with no matching migration, as Django computes them Fields declared in models but never migrated
Reverse direction (migrated but removed from models) Covered by Django’s comparison Not stated in the source
Database-level or backend-specific differences Outside the check’s comparison of model state Not claimed by the article
Typical use Developer machines and CI jobs with a working environment Cold runners and broken environments where the Django command cannot start

The reported timing, and how to read it

The author reports that model graphs from Zulip, Saleor, Wagtail, django CMS, and Mezzanine parse together in about 20 ms on a laptop. Three qualifications apply. The figure is the author’s own report, not an independently verified benchmark. The indexed text does not specify the hardware or the measurement method. And the post’s publication year was not visible in the text available for this summary, so the figure should be read as a single author-reported observation rather than a current measurement for any given version of those projects.

The figure is still useful as a signal that a source-only pass is cheap enough to run on every commit, which is the practical argument for placing it early in a pipeline.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Deciding which check to run

  • If makemigrations --check runs reliably in your CI, keep it. It covers the comparison that Django itself performs.
  • If your lint stage runs before dependencies are installed, or a developer environment cannot import settings, a static declared-but-unmigrated check can still catch the most common failure at low cost.
  • Do not read a passing static check as proof that the migration history is complete or correct. It only establishes the one direction it covers.

The original post by FROWNINGdev is at I built a Django linter that never imports Django on DEV Community. Installation steps, repository details and the supported Django versions were not available in the text used for this summary, so check the post directly before adopting the tool.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Bottom Line

“”

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.