Add a new class for managing lists of migrations.

Review Request #11094 — Created July 23, 2020 and submitted — Latest diff uploaded


Django Evolution


When the migrations support was added, all call sites assumed they were
working with a particular structure internal to Django's migrations
code. These were represented as lists of (app_label, migration_name)
tuples, which were pretty easy to manipulate, and all call sites just
iterated through them, filtered them, or otherwise manipulated them as

Django 3.0 changed the structure internally. Some parts still use the
list of tuples form, while others use a dictionary mapping
(app_label, migration_name) keys to Migration instances. While this
change doesn't add support for that, it does address the problem that
arose of code assuming it was working with lists of tuples.

There's now a new MigrationList class, which tracks lists of
migrations, recorded internally as dictionaries containing app_label,
name, migration, and recorded_migration keys. These are sufficient
to represent migrations for all versions of Django.

Code can now focus on these higher-level manipulations of lists of
migrations without worrying at all about internal structure. That can be
translated to the appropriate format only as needed. This keeps calling
code stable and maintainable, and allows us to clean up a fair amount.

An upcoming change will build on this to translate the structure to
Django 3.0's requirements.

Unit tests pass for all supported versions of Django and Python.