feincms / django-tree-queries

Adjacency-list trees for Django using recursive common table expressions. Supports PostgreSQL, sqlite, MySQL and MariaDB.
https://django-tree-queries.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
427 stars 27 forks source link

How to show tree in django admin? #37

Closed Baltrunas closed 1 year ago

Baltrunas commented 2 years ago

It's possible to show tree like djano-mptt-admin?

matthiask commented 2 years ago

You could use https://feincms3.readthedocs.io/en/latest/ref/admin.html#feincms3.admin.TreeAdmin for this.

image

Baltrunas commented 2 years ago

Will be better to add this to documentation. Also it's work very strange with ordering if use "position" field to order.

It's possible to re-save all childs is some field was changed? I have slug field and URL field that generate path by all parent chain, If parent was change all child urls must be updated, feincms3 do some on move but only with "position" field

matthiask commented 2 years ago

Will be better to add this to documentation. Also it's work very strange with ordering if use "position" field to order.

I'm not sure what you mean. It seems to work fine here? The code is being used in many projects.

It's possible to re-save all childs is some field was changed? I have slug field and URL field that generate path by all parent chain, If parent was change all child urls must be updated, feincms3 do some on move but only with "position" field

feincms3 does contain the code to recursively update the path of all descendants here:

https://github.com/matthiask/feincms3/blob/511b789f2be78e2ece4d0c787ba5db79dc1b6023/feincms3/pages.py#L177-L214

I'm using the save_descendants keyword argument to avoid the recursion when recursing already. The feincms3 also checks that the resulting paths are all unique. It is a bit tricky but I think the code should be relatively straightforward to follow; it's also quite well tested.

xrmx commented 1 year ago

@matthiask what do you think on the possibility of adding the TreeAdmin code to this package?

matthiask commented 1 year ago

@xrmx No strong objections there, I'm just not completely sure that the feincms3 TreeAdmin is the best tree management UI there is. It doesn't have to be though, so maybe that's fine.

zakx commented 1 year ago

I think I have the same issue that was described earlier:

Also it's work very strange with ordering if use "position" field to order.

It looks like just adding the TreeAdmin code to my project results in a view that does get the depth display right, but doesn't have the correct ordering for the depth display to make sense. That's because the model admin view seems to use the ordering from the Meta class of the model, which is ordering by position as suggested in the documentation.

It looks like this:

It should look like this:

The database table looks like this:


                  id                  | name  | comment | position | label_template_id |              parent_id
--------------------------------------+-------+---------+----------+-------------------+--------------------------------------
 00000000-0000-4000-8000-000000000000 | root  |         |        0 |                   |
 89b82dc3-2dd3-4c43-9dce-60e7a310004c | test  |         |        0 |                   | 00000000-0000-4000-8000-000000000000
 551cd75a-fce3-47a8-9588-6fe8d9bf9f11 | test3 |         |        0 |                   | 00000000-0000-4000-8000-000000000000
 8b1a6fe7-0e38-41d3-ad3b-c088cc26397f | test4 |         |        0 |                   | 551cd75a-fce3-47a8-9588-6fe8d9bf9f11
 197e38b0-d545-4507-a340-7ce61139d1cb | aaaa  |         |        1 |                   | 89b82dc3-2dd3-4c43-9dce-60e7a310004c
 c9d2dfae-03bb-476f-a10d-50d1e9b511d9 | test2 |         |        2 |                   | 89b82dc3-2dd3-4c43-9dce-60e7a310004c
(6 rows)

For completeness sake, the admin.py excerpt looks like this:

@admin.register(Storage)
class StorageAdmin(TreeAdmin):
    readonly_fields = ("id",)
    actions = [print_labels]
    search_fields = ["name", "comment"]
    list_filter = ("label_template",)
    # inlines = [StorageInline]
    list_display = (
        "indented_title",
        "move_column",
    )

And the model looks like this:

class Storage(TreeNode, UUIDModelHelpers):
    id: UUIDField = UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name: CharField = CharField(max_length=255)
    comment: TextField = TextField(null=True, blank=True)
    position: PositiveIntegerField = PositiveIntegerField(default=0)

    label_template: ForeignKey = ForeignKey(
        "LabelTemplate", null=True, blank=True, on_delete=models.SET_NULL
    )

    class Meta:
        ordering = ["position", "name"]

When I remove the ordering in the model, the TreeAdmin view gets the parents right, but does not care about ordering anymore, which also isn't ideal.

Am I missing anything here? For me it looks like the feincms3.TreeAdmin just doesn't support ordered models and something like numeric positions.

matthiask commented 1 year ago

Hi @zakx

First, sorry for the late response!

I'm wondering. The code doesn't take more than one ordering field into account right now. I suspect that the problem is (or was) that test and test3 have the same position value, and the ordering code doesn't like that. As you can see here the name field in ordering isn't even looked at: https://github.com/matthiask/django-tree-queries/blob/793b40c03ad246d59542bdce8bbc8e9d03dedc17/tree_queries/compiler.py#L27-L31

I haven't done any research on this but I'm not sure if PostgreSQL's ARRAY type supports e.g. mixing integers and strings. If it did it probably wouldn't be too hard to support more than one field to order siblings by; but other databases would be more problematic.

django-tree-queries should at the very least emit a warning if you have more than one field in ordering as long as I or someone else hasn't found a way to support more than one field without tanking performance.

matthiask commented 1 year ago

I don't think the behavior is totally ideal right now but at least you're being warned if you're using more than one field in ordering. So I'm gonna close this issue.