Proposed Grid Refector

183 views
Skip to first unread message

Massimo

unread,
May 17, 2025, 2:28:25 AM5/17/25
to py4web
I would like to propose a grid refactor


BEFORE:

@action("grid")
@action("grid/<path:path>")
@action.uses(db, "generic.html")
def _(path=None):
grid = Grid(path, db.thing)
return locals()

urls are 

/app/grid/
/app/grid/select
/app/grid/details/{id}
/app/grid/edit/{id}

AFTER:

@action("grid")
@action.uses(db, "generic.html")
def _():
grid = Grid(db.thing)
return locals()

urls are 

/app/grid/
/app/grid?page=select
/app/grid?page=details&id={id}
/app/grid?page=edit&id={id}

Basically simpler API and routing but more complex URLs but they can still be bookmarked.
This change can be made backward compatible but it would add code complexity.
I would prefer to make it backward incompatible since the code change is easy.

Thoughts?

Ali

unread,
May 18, 2025, 1:20:06 AM5/18/25
to py4web
I like the proposition a lot. There shouldn't be a need for two separate actions.

- ali

Massimo

unread,
May 18, 2025, 11:54:40 PM5/18/25
to py4web
Had to remove the delete confirmation alert and replace it with a confirmation page since we currently have an insecure object reference vulnerability. An attacked can trigger a malicious record delete by posting a link to the delete page. It does not require POST nor confirmation. Fixed in the branch.

I think I am going ahead with these changes, but I would like Jim's blessing. :-)

Tom Clerckx

unread,
May 19, 2025, 4:35:11 AM5/19/25
to py4web
While I'm not against it, I think it will be quite some code refactoring for many users.
This may hold people back from updating the framework code.

Tom.

Jim Steil

unread,
May 19, 2025, 1:06:15 PM5/19/25
to py4web
Massimo - you have my blessing on anything you want to alter. I've been noticeably absent from the group for a year or so with another project at my company that is taking all my available time. 

We're implementing Odoo as our ERP and it is a massive job here. I hope to get back and be more active in this community once we go live, hopefully later this summer.

-Jim

Massimo

unread,
May 19, 2025, 1:20:40 PM5/19/25
to py4web
Thank you Jim. We need a Odoo alternative in py4web. LOL

Anyway, the minimal change is existing code that use the grid is just to no pass the first path argument to it, and everything will work with 2 exceptions: links to custom edit/details pages (I do not think anybody but Jim is using that) and external links to internal grid pages (something that is not supported anyway, in fact I was planning to explicitly prevent that by signing grid pages like the web2py used to do)

David Manns

unread,
Jun 2, 2025, 9:31:13 AM6/2/25
to py4web
It appears that the actual implementation uses a 'mode' parameter, not 'page', where mode can be, e.g. 'edit', 'display', 'new', 'delete'

Massimo DiPierro

unread,
Jun 2, 2025, 10:18:41 AM6/2/25
to David Manns, py4web

Correct. Page had a conflict with pagination


--
You received this message because you are subscribed to the Google Groups "py4web" group.
To unsubscribe from this group and stop receiving emails from it, send an email to py4web+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/py4web/7b5ae919-1cb9-4744-82e1-9cff4dd06854n%40googlegroups.com.

David Manns

unread,
Jun 6, 2025, 11:01:13 AM6/6/25
to py4web
There is a slight problem with the delete confirmation page, which is that the controller can't distinguish between the call from clicking the delete button from the clicking of the confirm button on the confirmation page. This is a problem because if there are secondary actions needed (for instance, deleting some related records), these should be performed only when the confirm button is pushed.
Could the delete confirmation be a distinct mode?

A second issue is that if a record is deleted by ticking 'delete record' in the Edit screen, the record is deleted without confirmation. Perhaps the delete checkbox in the Edit screen should be omitted regardless of the setting of the grid delete parameter?

Massimo

unread,
Jun 7, 2025, 1:04:16 AM6/7/25
to py4web
I am not against this but I would like to hear more opinions.

David Manns

unread,
Jun 7, 2025, 4:23:43 PM6/7/25
to py4web
I can instead deal with post-delete clean up requirements by checking for necessary clean up in the subsequent 'select'. So I don't really need to distinguish the 'confirm delete' inner call.

I still think that the 'delete record' checkbox in the 'edit' case should either be removed or should also go through the confirm process.

Thanks

David

Tom Clerckx

unread,
Jun 8, 2025, 11:18:48 AM6/8/25
to py4web
Giving my personal opinion about this: 

The additional confirmation in the edit-and-delete case is not needed.
The thought behind this is that in both cases (direct delete or delete via edit) two actions are required, providing the user with the option of a second thought.

edit-delete:
1) User selects the delete option
2) User confirms the change by pressing the submit button

delete-button:
1) User presses the delete button
2) User confirms the deletion

Instead of pushing yet another confirm button in the edit-delete case, I would rather do something different.
E.g. when the delete option is selected, you could change the color of the submit button to red and/or change the text from 'submit' to 'delete'

Tom.



Jorge Salvat

unread,
Jun 20, 2025, 2:11:12 PM6/20/25
to py4web
Hi, testing new Grid, 'details' is not passed in the URL.
To find out mode I'm using this function:

def get_mode():
    if "mode" in request.query:
        return request.query.get("mode")
    if "id" in request.query:
        return "details"
    return "select"

@action("wgrid", method=["POST", "GET"])
@action.uses("generic.html", db)
def _():
    mode = get_mode()
    print(mode)
    grid = Grid(db.person, editable=True, deletable=True)
    return dict(grid=grid)


Could we integrate  get_mode  into Grid.py ?  
or maybe there is a simpler solution?
Message has been deleted

Massimo

unread,
Jun 21, 2025, 3:08:01 AM6/21/25
to py4web
there is a

node = Grid.parse(request.query)["mode"]

which does what your get_mode() does.

get_parent(parent_field) is also in grid.py

Reply all
Reply to author
Forward
Message has been deleted
0 new messages