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.
Create a (default) object of the foreign model. It will automatically have id=1 (if no object existed yet). Change your foreignkey field by replacing null=True, blank=True by default=1 to associate that new object you created to all existing rows.
If you have more than one foreign key, a validation error will be raised. Your intermediate model must contain one - and only one - foreign key to the source model (this would be Group in our example). If you have more than one foreign key, a validation error will be raised.
What is ForeignKey in Django? ForeignKey is a Field (which represents a column in a database table), and it's used to create many-to-one relationships within tables. It's a standard practice in relational databases to connect data using ForeignKeys.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With