-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify adding new views to ModelAdmin #10
Comments
@JamesRamm thanks for posting. Some really good points here! I've faced a similar frustrations myself (particularly with ButtonHelper), and would love to help refactor things to make things easier to extend. Not having attributes or methods on the In regards to what you said here:
Hiding features by editing the ButtonHelper would never be an approach I'd recommend, because whether the ButtonHelper shows the button or not, the URLs for those actions (and the views to perform them) are still registered, and likely still accessible by going to the URL directly. The recommended approach would be to simply not grant users the relevant permissions required for those actions (ButtonHelper only shows buttons for actions that the current user has permission to perform) |
I think we can safely split actions into 4 groups:
And less common:
So long as a more generic solution wouldn't lock out support for the last two, I think it would be worthwhile pursuing this. Even if the end-result wasn't quite as simple as defining a few tuples, cutting out some of the repetition throughout, and reducing the number of manual steps for adding custom views would definitely be positive. |
@JamesRamm what would you think to introducing a class similar to the one below for defining all of the things related to a specific action? I think most things could be introspected from that (urls, button stuff, permission checks etc). And if it had URL-related methods that could be overridden for types 3 and 4 (above), that should be pretty much everything covered, right?
|
Put together a quick proof of concept for this class here: https://github.com/rkhleics/wagtail/blob/modeladminactions/wagtail/contrib/modeladmin/actions.py I'm thinking that the actions themselves would be defined as a list of tuples, where the 'codename' (e.g add/edit/delete) would be the first value, and the second would be a dictionary of args to be used to initialise a Other ideas welcomed :) |
@ababic I agree with your 4 'groups' of actions, although I might also add a 5th group where you have an action not tied to a specific view? This would support, essentially, buttons with javascript handlers (ajax updates and whatnot - I would also allow any generic button attributes (like id) to be specified).
Ideally, the existing default actions - in
So you can then do:
Or
It looks like it would nicely reduce adding an action to just filling in some parameters and creating a view. |
@JamesRamm I envisaged the I did envisage the existing actions being migrated to the new interface too... the ModelAdmin class could then cycle through them to create the URLs list etc, and we could probably drop all of the Separate sets of actions would need to be defined for page-type models and non page-type models too, as there are differences between the two. |
@JamesRamm Love your idea of having the default options configured in the same file so that they can be imported more easily. One thing I neglected to explain before, but I'd probably suggest that 'codenames' be made to conform to something like |
Im onboard with all that. Would it be possible to keep all the existing functionality with deprecation warnings on functions, while still merging the new method in full? Then provide deprecation warnings for the next release or so (whatever the wagtail convention is). On conventions...a small note; on your A regex and collision check is a great idea yes. Your |
I think we will likely need to take some steer from the core team RE deprecation a little later down the line, as I feel it could probably be the biggest challenge here as things pan out. Great point on conventions on use of And good point about collision checking. I feel like a nicely-worded 'ImproperlyConfigured' exception to notify users about those on |
@JamesRamm In regards to something you said about the 5th group of actions:
I'm beginning to think it will be difficult to fully support this with just a single definition on the model class. E.g. in the case of adding an 'id' attribute, you wouldn't ever want the same ID to be added to all buttons on that type. In almost all examples I can think of, you'd want to have unique values for each instance of the button, likely using field values from the relevant model instance. I feel like the only solution for buttons like that will be to create a method that accepts a model instance, like the methods that currently need to be defined on the |
@ababic, thats true. I was thinking you would probably also want to set some Yes, best would be a method along the lines of |
Yeah that's probably better as a future thing. Although, in the meantime, we can still support the definition of individual 'button definition' methods, and there's also the |
+1 (great enhancement) |
Just wanted to flag up a few related ModelAdmin issues. Ideally, I'd like the following to precede this work, because it will help keep the view-related stuff simple, and I think ButtonHelper is easily weakest part of
And possibly the following too, because it will remove some unnecessary cruft from
I also never really considered this before, but I feel like this work could make something like the following easier, by letting you flag certain actions as 'bulk actions' or something:
|
Would #7 not initially complicate resolving this issue, since, if I understand, it is about adding new features...new features would be easier to add once this refactor is done, since this should make extension/future maintenance a bit easier? Once this issue tackled, then #7 becomes a slightly simpler question of 'how can we do nested |
I'm thinking #7 should probably be de-scoped, so that we can at least have
I think we've already agreed that it will be possible to support simple button definitions within the |
Right, yes I see where you are coming from now. 👍 |
Hey @JamesRamm. Quick status update: The work I suggested should precede this work is coming along:
I've begun working on this particular feature as a (not yet working) third-party app, bundled together with the new ButtonHelper stuff I've done (the two ideas complement each other incredibly well), so that It will be easier to demo and collect feedback on (https://github.com/ababic/waddleadmin/). But, I do kinda need wagtail/wagtail#3542 to be merged before I can get that working properly. Do please check out |
@ababic |
Any progress on this? |
Hi @Adrian-Turjak. There's certainly progress, but this was always going to be a challenge. I'm trying to tackle a few related aspects of this functionality separately, in smaller, more focussed PRs, in an aid to make things easier/quicker to review. But they haven't been moving as quickly as I'd hoped. wagtail/wagtail#3542 had to be cancelled and has been replaced with wagtail/wagtail#3626, which I hope will be reviewed soon. I think the focus has then got to be on getting https://github.com/ababic/waddleadmin/ into a state that will show all of the various components working together as intended. That's probably the best way to gather input from other developers, and get things into a shape that the core team will be happy with / want to prioritise. |
@ababic Fantastic! I'll try and keep an eye on this will be happy to review and play with https://github.com/ababic/waddleadmin/ when you've got it in a state you're happy with. :) As much as I dislike the default django admin, the ability to add actions to it was easy, and useful, so I'm really hoping for something just as nice for the wagtail admin! Because as the OP has said, the existing process is a little roundabout. :( |
When using
ModelAdmin
, if you wish to add a new view alongside inspect/create/edit/delete, you need to do the following:Inherit from
ButtonHelper
and add a new function for your view link button, which follows the same template ascancel_button()
/inspect_button()
etc..Override
get_buttons_for_obj
to add your custom button...which basically involves reimplementing it exactly the same then tagging your button on to the end of thebtns
array. (we can callsuper
and tag it on the end of the returned array, although this still involve repeating some of the logic within the base function)In your custom
ModelAdmin
child class, overrideget_admin_urls_for_registration
to add the url for your new view onto the returnurls
array.In the same class, implement a new function to return your view (i.e. it should do the same as
ModelAdmin.inspect_view
but return your own view class).Implement the actual
View
class by e.g. inheriting fromInspectView
This is quite a lot of boilerplate. Similarly if you wish to remove a view/button (e.g. preventing models from being deleted), you have to reimplement a function to do exactly the same thing but without the button you wish to remove.
I wonder if there is way to easily, dynamically register views/buttons in
ModelAdmin
?I am not sure how this could work yet, but perhaps a class attribute which will take an array of tuples with the view class and button name? We would then need the necessary logic to register these views.
Allowing new views to be registered like this would not only make it more generic, but allow a lot of the repeated boilerplate within the base classes to be condensed (e.g. functions like
index_view
andcreate_view
onModelAdmin
, orcreate_button
,index_button
etc onButtonHelper
which share much of the same logic)I will happily do the work to this effect, but I think it needs some discussion and consensus before beginning.
Another interesting possibility would be to allow buttons to be registered which are not attached to a view ..this could be achieved by simply setting the
url
parameter to''
, but it would be useful to be able to specify the htmlid
of the created<a>
element.(e.g. to allow javascript actions etc...)
The text was updated successfully, but these errors were encountered: