-
-
Notifications
You must be signed in to change notification settings - Fork 31
Description
Once again, great library, and I'm back to trying to use it again after using mptt but running into a real PITA concurrency issue where it has trouble creating distinct, unrelated nodes concurrently without corrupting the tree_ids. Given the project is unmaintained, potential fixes look like they've gotten stuck in PR limbo.
Anyway, I had a lot of trouble getting the right django-tree-queries "tree field" annotations on a model in a certain situation that I've finally solved. I'd like to confirm I understand the library behavior properly and suggest some documentation updates (which I'm happy to contribute as a PR).
Here's what I was doing.
I have a model that inherits from TreeNode
. I also set a custom manager via TreeQuerySet.as_manager(with_tree_fields=True)
. I want to be able to, given a pk for an instance of this model type, make a copy of the instance with some, slightly different attributes and then make the original instance a child of the new instance. It's essentially a rudimentary VCS.
I ran into two problems trying to do this "version control":
- When I create the new object via
Model.objects.create(...)
, I kept getting an error thattree_depth
was not an attribute on the new instance. I tried torefresh_from_db()
thinking maybe that could help, but no dice. Eventually, I realized that, if I took the pk of the new instance and immediately refetched it viaModel.objects.get(id=id)
, I got the tree field annotations. - One thing that was throwing me a bit was the original instance had the proper parent attribute but the tree_depth was still 0. As with the new instance,
refresh_from_db()
was no help. Like the new instance, I eventually realized I needed to requery it from the database and my problem was solved.
After discovering working this out and then very closely rereading your documentation, I think this is expected behavior as you state the manager adds the tree fields to queries by default:
Create a manager using TreeQuerySet.as_manager(with_tree_fields=True) if you want to add tree fields to queries by default.
So, I think it's the case that a database refresh will have no effect on these fields as they're not actual database fields but rather calculated fields. Furthermore, create()
, I guess, isn't a query?
So, couple questions:
- Can you confirm my understanding is correct and that the only way to get the proper, accurate tree fields is to use
objects.get()
orobjects.filter()
? - Not having written a Django manager before, is there an easy way to extend the
TreeQuerySet
code to add these annotations to the model.create()
behavior too? - Likewise, do you know if there is a way to override the
refresh_from_db()
behavior to annotate the tree fields? - Finally, regardless of your answer to 1, 2 or 3, would you welcome some update documentation making this behavior clearer? It took me some time to figure this out, and, while it may be clear to people familiar with the inner workings of Django managers, I'd love to save the less enlightened some time.