1👍
you can set the initial values in the init method of the form.
Refer to them as self.fields[‘manager_staff’].initial.
Like so:
class PersonAdminForm(forms.ModelForm):
manager_staff = forms.ModelMultipleChoiceField(
queryset=Person.objects.all(),
required=False,
)
def __init__(self, *args, **kwargs):
super(PersonAdminForm, self).__init__(*args, **kwargs)
if self.instance.id is not None:
selected_items = [ values[0] for values in Person.objects.filter(
#whatever your filter criteria is
) ]
self.fields['manager_staff'].initial = selected_items
- Django-registration app and Django 1.5 custom user model
- Django: override get_FOO_display()
- Grouping Conditions in Django template if statement
- Exposing model method with Tastypie
- Django override_settings won't work for running multiple tests
0👍
This might end up being one of those limitations. Here’s what I managed to come up with. It’s possible to create a custom Form and pass that to the admin site to use for rendering a page. However, what I couldn’t get was for it to properly show the initial value properly. Perhaps someone better at Forms can come along with some uber-cool-secret-meta API that I don’t know about and fix this.
models.py
class Person(models.Model):
# ...
manager = models.ForeignKey('self', related_name='staff', null=True, blank=True)
def manager_staff(self):
return self.manager.staff.all()
admin.py
class PersonAdminForm(forms.ModelForm):
manager_staff = forms.ModelMultipleChoiceField(
initial='manager_staff', # Can't get this to work
queryset=Person.objects.all(),
required=False,
)
class Meta:
model = Person
class PersonAdmin(admin.ModelAdmin):
form = PersonAdminForm
def save_model(self, request, obj, form, change):
for id in form.data.getlist('manager_staff'):
# This is kind of a weak way to do this, but you get the idea...
p = Person.objects.get(id=id)
p.manager = obj.manager
p.save()
super(PersonAdmin, self).save_model(request, obj, form, change)
admin.site.register(Person, PersonAdmin)
0👍
Here’s what I came up with based on the answers from T. Stone and nicoechaniz. The initial data is provided in much the same way as nicoechaniz does it. For the saving you have to be careful do deal with the case of a completely new Person as well as editing an existing Person. That’s what makes the save()
method complicated, depending on non-publicized parts of the ModelForm API. Really this should be built into Django. I imagine it’s a commonly sought after feature.
class PersonAdminForm(forms.ModelForm):
staff = forms.ModelMultipleChoiceField(
queryset=Person.objects.all(),
required=False,
)
class Meta:
model = Person
def __init__(self, *args, **kwargs):
super(PersonAdminForm, self).__init__(*args,**kwargs)
if self.instance.pk is not None:
self.initial['staff'] = [values[0] for values in self.instance.staff.values_list('pk')]
def save(self, commit=True):
instance = super(PersonAdminForm, self).save(commit)
def save_m2m():
instance.staff = self.cleaned_data['staff']
if commit:
save_m2m()
elif hasattr(self, 'save_m2m'):
save_old_m2m = self.save_m2m
def save_both():
save_old_m2m()
save_m2m()
self.save_m2m = save_both
else:
self.save_m2m = save_m2m
return instance
save.alters_data = True
class PersonAdmin(admin.ModelAdmin):
form = PersonAdminForm
- Add checkbox and delete actions to customized Django admin change_list
- Add custom Django admin action
- Django Rest Framework invalid username/password
- Django createview with success_url being the same view?