django admin动态设置changeform初始数据

时间:2014-11-06 17:19:42

标签: django django-forms django-admin

我使用默认的m2m小部件通过中间模型实现m2m关系。我使用Person模型相关的ProjectMembership模型。

到目前为止,我已经成功地在Person更改表单中显示默认m2m小部件并正确创建了中间模型实例,但我的问题是在Person正在填充小部件时修改。

这是我使用PersonAdmin

的表单类
class PersonForm(forms.ModelForm):
    projects = forms.ModelMultipleChoiceField(models.Project.objects.all(),
                                              widget=widgets.FilteredSelectMultiple(
                                                  verbose_name="Projects",
                                                  is_stacked=False,
                                                  attrs={'rows':'10'}))
    projects.required = False
    class Meta:
        model = models.Person
        fields = ['name', 'last_name', 'personal_id_number',
                  'personal_id_type', 'administrative_viability',
                  'observations']

    def save(self, commit=True):
        ret = super(PersonForm, self).save(commit)
        for p in self.cleaned_data['projects']:
            models.Membership.objects.create(person=self.instance, project=p)
        return ret

PersonAdmin本身:

class PersonAdmin(admin.ModelAdmin):
    form = PersonForm

    def get_changeform_initial_data(self, request):
        initial = super(PersonAdmin, self).get_changeform_initial_data(request)
        initial['projects'] = models.Person.get(pk=initial['person']).project_set.all()
        return initial

我尝试在方法projects中设置get_changeform_initial_data的初始值,但它不起作用。总的来说,它似乎被忽略了,好像我没有正确地覆盖它。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:4)

This question让我想到了覆盖__init__的{​​{1}}方法:

PersonForm

我仍然不知道为什么覆盖def __init__(self, *args, **kwargs): if 'instance' in kwargs: person = kwargs['instance'] initial = {'projects': person.project_set.all()} kwargs['initial'] = initial super(PersonForm, self).__init__(*args, **kwargs) 无法正常工作。

答案 1 :(得分:0)

get_changeform_initial_data仅在不是更改时被调用。我知道这没有任何意义。我怀疑这是一个错误。

请参阅第1573行的django/contrib/admin/options.py,这是整个Django中唯一对此方法的调用:

            if add:
                initial = self.get_changeform_initial_data(request)
                form = ModelForm(initial=initial)
                formsets, inline_instances = self._create_formsets(request, form.instance, change=False)
            else:
                form = ModelForm(instance=obj)
                formsets, inline_instances = self._create_formsets(request, obj, change=True)

更新:Looks like it's deliberate。我会问开发商为什么它会这样工作。