Skip to content

Fix site duplication so that the clone ID is used as the tree ID if the original site doesn't have a parent - #5646

Open
PartyNell wants to merge 1 commit into
masterfrom
fix_site_duplication
Open

Fix site duplication so that the clone ID is used as the tree ID if the original site doesn't have a parent#5646
PartyNell wants to merge 1 commit into
masterfrom
fix_site_duplication

Conversation

@PartyNell

Copy link
Copy Markdown
Contributor

Description

If the duplicate site does not have a parent, set its tree ID to its ID. Otherwise, the children of the initial site will be unable to retrieve the root of the hierarchy because there are multiple roots (the root of a hierarchy is defined by the tree ID).

Related Issue

Checklist

  • I have followed the guidelines in our Contributing document
  • My code respects the Definition of done available in the Development section of the documentation
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes
  • I added an entry in the changelog file
  • My commits are all using prefix convention (emoji + tag name) and references associated issues
  • I added a label to the PR corresponding to the perimeter of my contribution
  • The title of my PR mentionned the issue associated

AI requirements

Skip the checkboxes below 👇 If you didn't use AI for your contribution

  • I used AI assistance to produce part or all of this contribution
  • I have read, reviewed, understood and can explain the code I am submitting
  • I can explain and discuss my work to a maintainer
  • I pasted the prompt used and mentioned the model used below

@codecov

codecov Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.54%. Comparing base (01031f9) to head (cdd70c4).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #5646   +/-   ##
=======================================
  Coverage   98.54%   98.54%           
=======================================
  Files         274      274           
  Lines       23034    23040    +6     
=======================================
+ Hits        22699    22705    +6     
  Misses        335      335           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cypress

cypress Bot commented Aug 17, 2026

Copy link
Copy Markdown

Geotrek-admin    Run #17658

Run Properties:  status check passed Passed #17658  •  git commit b3047ed3ed ℹ️: Merge cdd70c46d7e9c8fd7edf663b6cf25ca8c8a51ade into 01031f9c4164c66e0595dc36ec91...
Project Geotrek-admin
Branch Review refs/pull/5646/merge
Run status status check passed Passed #17658
Run duration 02m 09s
Commit git commit b3047ed3ed ℹ️: Merge cdd70c46d7e9c8fd7edf663b6cf25ca8c8a51ade into 01031f9c4164c66e0595dc36ec91...
Committer Nell Party
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 22
View all changes introduced in this branch ↗︎

Comment thread geotrek/outdoor/models.py
https://github.com/GeotrekCE/Geotrek-admin/issues/5461
"""
clone = super().duplicate(**kwargs)
if clone.parent is None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread geotrek/outdoor/models.py
Comment on lines +509 to +510
clone.tree_id = clone.id
clone.save(update_fields=["tree_id"])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je trouve cette solution risquée pour plusieurs raisons :

  • que se passe-t-il si la valeur de clone.id est déjà attribuée à un arbre ? je ne sais pas comment sont gérées les valeurs de tree_id mais imaginons qu'elles fonctionnent comme une séquence en sql. si on supprime des arbres puis on en recrée et modifiant les liens entre sites, on peut se retrouver avec des tree_id supérieurs ou égaux aux pk des sites. on ne sait jamais ce qui peut se passer et comment le code (de gta ou de la lib) peut évoluer
  • on attribue à la main une valeur qui fait partie de tout un système géré sous le capot dans une lib. il y a le risque de, par exemple, passer à côté d'une autre valeur à modifier, et si ce n'est pas le cas actuellement, la lib peut évoluer -> il faudra non seulement ne pas passer à côté de l'évolution, mais en plus faire une PR dédiée pour être compatible avec la nouvelle version.

Je n'ai pas testé, mais utiliser la méthode move_to avec target à None me semble être une solution plus safe car tout est géré par la lib :
https://django-mptt.readthedocs.io/en/latest/models.html#move-to-target-position-first-child

Qu'en penses-tu ?

@PartyNell PartyNell Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Après avoir testé move_to, il ne fonctionne pas dans ce cas.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Le soucis c'est que move_to déplace un objet en racine uniquement s'il n'est pas déjà en racine. Hors dans notre cas c'est pas le cas.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Voilà la solution que j'ai trouvé mais c'est pas génial étant donnée qu'on utilise des méthodes qui ne sont pas censées être utilisées hors de la classe.

    def duplicate(self, **kwargs):
        """
        Duplicate the site and ensure that a duplicated root site gets its own tree ID.
        https://github.com/GeotrekCE/Geotrek-admin/issues/5461
        """
        clone = super().duplicate(**kwargs)
        if clone.is_root_node():
            manager = clone._tree_manager
            new_tree_id = manager._get_next_tree_id()
            clone.tree_id = new_tree_id
            clone.save(update_fields=["tree_id"])
        return clone

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sinon les autres solutions sont :

  • bouger artificiellement clone sur un autre arbre en tant que enfant puis faire un move
  • utiliser Site.objects.rebuild() qui reprend toutes les root et leur attribut un tree_id mais c'est coûteux en calcul

self.site_2 = SiteFactory.create(name="child_site", parent=self.site_1)
clone = self.site_1.duplicate()
self.assertNotEqual(clone.tree_id, self.site_1.tree_id)
self.assertEqual(list(self.site_2.get_ancestors()), [self.site_1])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vérifier plutôt/en plus que la valeur de retour de clone.get_family() ne contienne qu'un seul élément (clone lui-même) ?
On s'assure alors qu'on a bien créé un tout nouvel arbre : le clone n'a ni parent ni enfant.
Selon moi c'est plus complet et plus direct (donc plus compréhensible pour le lecteur) que vérifier les ancêtres de site_2.
https://django-mptt.readthedocs.io/en/latest/models.html#get-family

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants