So I have a working Mixin for an action that currently operates on all fields of the queryset. Instead of this, I would like the ability to specify which fields will be used by the action via the code for the Admin page.
For context, here is a brief portion of my Mixin:
class MyMixin:
def my_action(self, request, queryset):
model_to_update = apps.get_model(
app_label=<my_app>,
model_name=queryset.first().__class__.__name__)
...
for field in model_to_update._meta.get_fields():
# do cool stuff with all fields
...
return render(...)
Here is how the mixin is incorporated currently:
...
@admin.register(<Model>)
class ModelAdmin(MyMixin):
...
actions = ["my_action"]
...
... and what I would like to do is something along the lines of:
...
@admin.register(<Model>)
class ModelAdmin(MyMixin):
...
actions = [my_action(fields=['foo', 'bar',]]
...
... where foo
and bar
are a subset of the fields of ModelAdmin
.
Thank you in advance for any ideas! Apologies if this has already been asked elsewhere and I'm just phrasing it differently.
CodePudding user response:
You can write a factory function that returns an action. This doesn't require a mixin.
def action_factory(fields, description='some action'):
def my_action(self, request, queryset):
for field in fields:
# do cool stuff with fields and queryset
queryset.update(**{field:None})
my_action.short_description = description
return my_action
@admin.register(FooBar)
class FooBarAdmin(admin.ModelAdmin):
actions = [action_factory(
fields=['foo', 'bar'],
description='clear foo and bar'
)]