class SchoolAdminForm(forms.ModelForm):
students = forms.ModelMultipleChoiceField(
queryset=Student.objects.all(),
widget=FilteredSelectMultiple(verbose_name='students', is_stacked=False))
class Meta:
model = School
fields = ['your_school_fields_go_here']
def __init__(self, *args, **kwargs):
super(SchoolAdminForm, self).__init__(*args, **kwargs)
if self.instance:
# fill initial related values
self.fields['students'].initial = self.instance.student_set.all()
class SchoolAdmin(admin.ModelAdmin):
form = SchoolAdminForm
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
original_students = set(obj.student_set.values_list("id", flat=True))
current_students = set(map(lambda x: x.id, form.cleaned_data['students']))
if original_students != current_students:
add_to_school = current_students - original_students
Student.objects.filter(id__in=add_to_school).update(school_id=obj.id)
remove_from_school = original_students - current_students
Student.objects.filter(id__in=remove_from_school).update(school_id=None)