django管理员更改列表中的自定义list_editable字段,它不直接对应于模型字段

时间:2013-10-07 19:58:19

标签: python django django-admin

假设我的模型看起来像这样(这是一个简化的例子):

class Person(Model):
  first_name = CharField(...)
  last_name = CharField(...)

  def name():
    return first_name + ' ' + last_name

在管理员更改列表中将名称显示为单个列非常简单。但是,我需要一个可编辑的“名称”字段,该字段可从列表页面进行编辑,然后我可以解析该字段以提取和设置模型字段值。解析不是问题。我只是想知道如何在列表页面上创建一个不直接与模型字段对应的可编辑表单字段。

2 个答案:

答案 0 :(得分:23)

你应该能够在纯Python中做一些工作。基本上,您需要在管理类上使用get_changelist_form方法告诉它为您的实例使用自定义表单而不是默认ModelForm,然后正确初始化自定义字段的值(最方便的是在表单的__init__方法)并专门设置该表单的save行为,以设置first_namelast_name值。

这样的事情应该是一个开始:

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
        super(PersonChangeListForm, self).save(*args, **kwargs)

class PersonAdmin(admin.ModelAdmin):
    def get_changelist_form(self, request, **kwargs):
        return PersonChangeListForm

当测试为布尔值时,您还需要声明一个评估为list_editable的{​​{1}}值 - 如果True没有使用,则不使用formset的一些管理处理短路评估为list_editable

如果您没有其他字段可以编辑,则会变得更复杂。类验证要求True序列中的所有内容都是一个可编辑的字段,该字段也在list_editable中声明,而不是显示链接字段。我认为那里的选项要么覆盖admin类的list_display方法,即使changelist_view不成立,也要使用完整的处理,或者定义list_editable或{{1的自定义子类即使是空的,它也会评估为list,因此它可以通过验证。前者需要重复大量的标准代码,并且如果你升级会显着增加你的维护负担,而后者是违反直觉的黑客攻击,如果它有意想不到的后果,我一点都不会感到惊讶。

两者都不是好选项,所以我希望你至少有一个其他字段可以包含在tuple中。

答案 1 :(得分:2)

我刚尝试在管理员中快速模拟问题。似乎管理验证对于list_editable中未在模型上定义的字段失败。简而言之,你的问题的答案似乎是否定的。

但是,这并不意味着它不可行。使用一些Javascript,您可以使用X-editable

(或滚动您自己的),并使“名称”列可编辑。创建一个视图以验证数据并将其保存到模型中。设置X-editable字段'url'参数以发布到此URL。显然用login_required / permissions_required等装饰您的视图,以确保没有其他人可以编辑数据。