django-unfold
django-unfold copied to clipboard
Object-dependent actions
I would like my detail actions to be dependent (to be shown or hidden) depending on certain values contained in the fields. To do this I use the function get_actions_detail
, but it doesn't get the object obj
, so I can't access the fields.
I have seen both a pull request (closed without accepting) and an issue that the creator himself closes but not with a solution.
So my question is if right now there is any way to show or hide actions depending on object values?
If not, could the Pull Request be reconsidered? I think it is a minor change and provides functionality that may be useful to users (as evidenced by their votes).
Thanks in advance!
You may get the object id from request.path.
try:
obj_id = int(request.path.split("/")[-3])
except:
pass
Apart from this, you can “hide” unwanted actions in a formview by overriding get_actions_detail and/or get_actions_submit_line methods.
I’ll give you an example tomorrow.
Here's an example for your reference.
@admin.register(YourModel)
class YourModelAdmin(ModelAdmin
actions_detail = ["action_one"]
@action(description=("One"), permissions=["add"], url_path="one", attrs={})
def action_one(self, request: HttpRequest, object_id: int):
# your business logics
pass
def get_actions_detail(self, request: HttpRequest):
actions_detail = super().get_actions_detail(request)
try:
obj = YourModel.objects.get(id=int(request.path.split("/")[-3]))
except:
return actions_detail
actions = []
for action in actions_detail:
if "_action_one" in action.action_name and <your conditions>:
# do something here
else:
actions.append(action) # do nothing but only append the action
return actions
Another way is to create your own has_xxxx_permission method.
@admin.register(YourModel)
class YourModelAdmin(ModelAdmin
actions_detail = ["action_one"]
@action(description=("One"), permissions=["approve"], url_path="one", attrs={})
def action_one(self, request: HttpRequest, object_id: int):
# your business logics
pass
def has_approve_permission(self, request, obj=None):
# your business logics
return True if <conditions are met> else False
Added object_id for detail and submit line actions #552