Lets say I have a model School
and another model Student
.
class Student(models.Model):
school = models.ForeignKey(School)
name = models.CharField(max_length=100)
When a school is clicked in admin, then a new page appears showing school model fields and values.
I also want to select the already available list of students in that page itself.
Inlines is different, they will allow the ability to create and edit new records(student) belonging to that school. But I don't want that, lets assume there are already many student records available. I should be able to select them in admin from that school model page.
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):
original_students = obj.student_set.all()
new_students = form.cleaned_data['students']
remove_qs = original_students.exclude(id__in=new_students.values('id'))
add_qs = new_students.exclude(id__in=original_students.values('id'))
for item in remove_qs:
obj.student_set.remove(item)
for item in add_qs:
obj.student_set.add(item)
obj.save()
Do you mean that for a given School
instance you want to be able to get a list of all the students related to that school?
In which case you use the related_name
attribute of the ForeignKey relationship you specified. You haven't defined the related_name
where you do:
school = models.ForeignKey(School)
which is fine, it just uses the default related name which is the name of the child class (student) followed by _set
so for your school instance:
school = School.objects.get(pk=1)
students = school.student_set.all() # or .filter() or .exclude() etc
then you can pass that student queryset into your template.
You can disable the inline 'add' permission. See InlineModelAdmin