Repository navigation
JSON Report Reference
django-upgrade-report --format json writes one JSON document. Its shape is versioned by schema_version, now 1: adding a field keeps the version, renaming, removing or retyping one bumps it. Read kind before anything else.
-
schema_version(int): 1. -
kind(str):"report", one report for one project and target. Read it before the rest: later versions may write documents of other kinds. -
tool:name,versionandauthorof the tool that wrote the report. -
generated(str): ISO 8601 timestamp, UTC. -
framework(str): what the report is about:"django","wagtail"or"django-cms"(--framework). -
target(str): the version of that framework checked against, e.g."5.2". -
current_framework(str | null) andframework_requires_python(str | null): the project's version of the framework and what the target needs of Python; for Django the same as the two fields below. -
target_released(bool): false for a version that is not out yet (only classifiers count). -
current_django(str | null): the project's Django version: pinned, given with--from, or assumed from a range (a warning says so). For Wagtail or django CMS, the Django the project pins. -
django_requires_python(str | null):Requires-Pythonof the target Django. -
project_python(str | null): the project's Python asX.Y, when known. -
source(str): where the dependencies were read from. -
warnings(list of str): things that make the whole report questionable, show them first. -
notices(list of str): good to know, nothing to worry about, e.g. why the report is a health check of the Django the project already runs. -
counts(object): number of packages per status (ready,upgrade,check,blocked). -
packages(list): one object per Django-related package, most urgent first:name,current(pinned version or null),spec(requirement when not pinned, or null),latest,status,upgrade_to(release to move to, or null),phase("before","with"or null),reason,notes(list of str),last_release(ISO 8601 or null) andsource(where a package not from PyPI comes from, e.g."git https://github.com/org/fork", or null). A package with asourcewas judged by its own metadata, read locally, and never looked up.built_into_djangois null, or, when Django took over the package's job by the target, an object withsince(e.g."3.1"),replacement(e.g."models.JSONField") andsource(a URL where that is written down).prereleaseis null, or, for a package to check or blocked, the newest pre-release when it declares the target, or no longer excludes it for a blocked package: an object withversion(e.g."2.0rc1"),reasonanduploaded(ISO 8601 or null).majors_crossed(int or null): major versions betweencurrentandupgrade_to, counted by the releases in between, each 0.x minor as one; null without both versions or for calendar versions.changelog_url(the link the project labels as its changelog, else its GitHub releases page) andrepository_url(its GitHub repository), or null; both come from the project's own metadata on the index.direct(bool or null): true when the project names the package itself, false when only another dependency needs it, null when the source does not say (a lockfile without itspyproject.tomlorPipfile).origin(str or null): the requirement file line that pins or names it, as"requirements/base.txt:12", relative to the project; null for other sources.evidence(list): for a package to check, signs of support the metadata does not give, each withkind("readme","test-matrix"or"changelog"),text(also innotes-like form, e.g."README of 2.1 mentions Django 5.2") andurl(or null). They never change the status.upstream(list): with--evidence, for a blocked package or one to check without a sign, at most two issues or pull requests in its GitHub repository whose title names the target:kind("issue"or"pr"),state("open","closed"or"merged"),title(at most 80 characters, from outside: escape it),url,numberandupdated(ISO 8601 or null). -
not_on_index(list of str): dependencies the package index does not know. -
not_checked(list of str): dependencies the index could not answer for, even after retries. When not empty, the report is incomplete;warningssays why. -
external(list): dependencies not from PyPI, never looked up and not judged (no Django-related metadata could be read locally), as objects withnameandsource(e.g."git https://github.com/org/repo"). -
skipped_non_django(int): dependencies without a Django requirement. -
removals(list): what Django removed in the releases after the project's Django up to the target, from the "Features removed" sections of its release notes:version,text(the first sentence),url(the release notes),fixer(django-upgrade rewrites it) andused_in(where the project's code uses it, at most three places such as"mysite/settings.py:12", or null when the code was not read). Empty for a health check. -
unused(list of str): direct dependencies, Django-related or not, that the project's code never names (read locally); empty when the code was not read (--no-scan-code, a file as the project, no Python code, or too big to read). -
changes(object or null): with--baseline, what changed since that report:since(itsgenerated),target(its target),compared(false when that target is not this report's: then nothing is compared) anditems, most important first, each withname(null for a warning),kind("status","upgrade","new","gone"or"warning"),fromandto(e.g."blocked","upgrade first", a version, a warning, or null),direction("better","worse","same","new"or"gone") andtext. -
python(object or null): when the target Django needs a newer Python than the project uses, or--python-targetnames one, what every pinned dependency from PyPI needs on it:targetandcurrent(X.Y),packages(objects like those underpackages, withstatus"upgrade","check"or"blocked"andupgrade_tothe first release that runs on the target),readyandpure(how many run on it already, the second pure Python),silent(names whose release says nothing about Python),not_checked(names the index did not answer for) anddjango_note(str or null: whether your Django patch release declares the target Python, or which one does). -
commands(object or null): with--emit, the commands that carry out the plan:tool("uv","poetry","pdm","pip"or"pipenv"),steps, in order, each withphase("python","before","with"or"upgrade") andcommands(list of str, shell-quoted; for pip, comments with the lines to change, with the file and line when known), andleft_out(str, e.g."django-taggit (blocked)": packages that need a person). -
explain(object): for each package given with--explain, by canonical name, how its verdict came about: a list of objects withsection("inputs","release","search","phase"or"result") andtext, in the order they happened. Empty without--explain.
A path (--via) is a document of its own, "kind": "path": schema_version, kind,
tool, generated, target, via ("lts" or "each"), blocked_at (the
first step, from 1, with a blocked package, or null) and steps: one report as above per
step, each with "kind": "report", the first from the Django you run, every later one from
where the step before ends.
Several projects (more than one PROJECT, or --recursive) make a document of their own,
"kind": "multi": schema_version, kind, tool, generated, projects (one
per project, in path order: path and either report, a report as above, or error,
why there is none), blocking (every blocked package with the paths of the projects it
blocks, the most widespread first) and shared_upgrades (packages several projects upgrade
to the same version: version and projects).
django-upgrade-report --format json -o report.json
jq -r '.packages[] | select(.status == "blocked") | .name' report.json
jq '.counts' report.jsondjango-upgrade-report · MIT · by Daniel Kurdoghlian, Pushing Pixels · This wiki is generated from docs/wiki/: change it with a pull request.