我正在使用默认的m2m小部件通过中间模型实现m2m关系。我有使用Person
模型相关的Project
和Membership
模型。
到目前为止,我已经成功地以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
的初始值,但是它不起作用。总体来说,它似乎已被忽略,好像我没有正确覆盖它。
任何帮助将不胜感激!
[This question给了我一个重写我__init__
的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)
我仍然不知道为什么覆盖get_changeform_initial_data
无效。
get_changeform_initial_data
仅在not更改时才被调用。我知道这没有任何意义。我怀疑这是一个错误。
请参见第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)