Custom list_editable field in django admin change list, which doesn't correspond directly to a model field
You should be able to do this in pure Python with a bit of work. Basically, you need to use the get_changelist_form
method on the admin class to tell it to use a custom form rather than a default ModelForm
for your instances, then initialize the custom field's value properly (most conveniently in the form's __init__
method) and specialize the save
behavior of that form to set the first_name
and last_name
values.
Something like this should be a start:
class PersonChangeListForm(forms.ModelForm):
class Meta:
model = Person
name = forms.CharField()
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance')
if instance:
initial = kwargs.get('initial', {})
initial['name'] = '%s %s' % (instance.first_name, instance.last_name)
kwargs['initial'] = initial
super(PersonChangeListForm, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
# use whatever parsing you like here
first_name, last_name = self.cleaned_data['name'].split(None, 1)
self.cleaned_data['first_name'] = first_name
self.cleaned_data['last_name'] = last_name
return super(PersonChangeListForm, self).save(*args, **kwargs)
class PersonAdmin(admin.ModelAdmin):
def get_changelist_form(self, request, **kwargs):
return PersonChangeListForm
You will also need to declare a list_editable
value that evaluates to True
when tested as a boolean - some of the admin processing short-circuits without using the formset if list_editable
does not evaluate as True
.
If you have no other fields you want to be editable, this gets more complicated. The class validation requires that everything in the list_editable
sequence be an editable field that's declared in list_display
as well and is not a display link field. I think the options there are either to override the admin class's changelist_view
method to use the full processing even if list_editable
is not true, or to define a custom subclass of list
or tuple
that evaluates to True
even when empty so it can pass validation. The former would require repeating a great deal of standard code and significantly increase your maintenance burden if you ever upgrade, while the latter is a counterintuitive hack and would not at all surprise me if it had unexpected consequences.
Neither are good options, so I hope you have at least one other field that makes sense to include in list_editable
.
I just tried a quick mock-up of the problem in the admin. It seems that the admin validation fails for a field which is in list_editable that is not defined on the model. In short, the answer to your question seems to be no.
However, that doesn't mean it's not doable. With a bit of Javascript, you could use X-editable
(or roll your own), and make the "Name" column editable. Create a view to validate the data and save it to the model. Set X-editable field 'url' parameter to post to this URL. Obviously decorate your view with login_required / permissions_required etc, to make sure no-one else can edit the data.