@@ -521,3 +521,52 @@ The ``TreeAdmin`` provides:
521
521
- ``move_column ``: Provides move controls (cut, paste, move-to-root)
522
522
523
523
These are included by default in ``TreeAdmin.list_display ``.
524
+
525
+
526
+ Migrating from django-mptt
527
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
528
+
529
+ When migrating from django-mptt to django-tree-queries, you'll need to populate
530
+ the ``position `` field (or whatever field you use for sibling ordering) based on
531
+ the existing MPTT ``lft `` values. Here's an example migration:
532
+
533
+ .. code-block :: python
534
+
535
+ def fill_position (apps , schema_editor ):
536
+ ModelWithMPTT = apps.get_model(" your_app" , " ModelWithMPTT" )
537
+ db_alias = schema_editor.connection.alias
538
+ position_map = ModelWithMPTT.objects.using(db_alias).annotate(
539
+ lft_rank = Window(
540
+ expression = RowNumber(),
541
+ partition_by = [F(" parent_id" )],
542
+ order_by = [" lft" ],
543
+ ),
544
+ ).in_bulk()
545
+ # Update batches of 2000 objects.
546
+ batch_size = 2000
547
+ qs = ModelWithMPTT.objects.all()
548
+ batches = (qs[i : i + batch_size] for i in range (0 , qs.count(), batch_size))
549
+ for batch in batches:
550
+ for obj in batch:
551
+ obj.position = position_map[obj.pk].lft_rank
552
+ ModelWithMPTT.objects.bulk_update(batch, [" position" ])
553
+
554
+ class Migration (migrations .Migration ):
555
+
556
+ dependencies = [... ]
557
+
558
+ operations = [
559
+ migrations.RunPython(
560
+ code = fill_position,
561
+ reverse_code = migrations.RunPython.noop,
562
+ )
563
+ ]
564
+
565
+ This migration uses Django's ``Window `` function with ``RowNumber() `` to assign
566
+ position values based on the original MPTT ``lft `` ordering, ensuring that siblings
567
+ maintain their relative order after the migration.
568
+
569
+ Note that the position field is used purely for ordering siblings and is not an
570
+ index. By default, django-tree-queries' admin interface starts with a position
571
+ value of 10 and increments by 10 (10, 20, 30, etc.) to make it clear that the
572
+ value is not an index, but just something to order siblings by.
0 commit comments