Home > OS >  Limit choices to m2m field of a foreign_key
Limit choices to m2m field of a foreign_key

Time:07-16

I have these models

class SubjectTeacher(models.Model):
    teacher = models.ForeignKey(TeacherProfile, on_delete=models.CASCADE)
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
    SEMESTER_CHOICES = [("1st", "First Quarter"), ("2nd", 'Second Quarter'), ('3rd', 'Third Quarter'), ('4th', 'Fourth Quarter')]
    semester = models.CharField(choices = SEMESTER_CHOICES, default = "1st", max_length=3)
    students = models.ManyToManyField(StudentProfile, related_name="subjects")
    def __str__(self):
        return f'{self.subject.subject_name}  | {self.teacher.user.first_name}'
    class Meta:
        constraints = [
            UniqueConstraint(fields = ["teacher", "subject"], name = "Unique Subject Teacher")
        ]

class StudentGrade(models.Model):
    subject_teacher = models.ForeignKey("SubjectTeacher", on_delete=models.CASCADE)
    student = models.ForeignKey('StudentProfile', on_delete=models.CASCADE)
    grade = models.IntegerField()



now I want StudentGrade.student to be based on what is selected (in django-admin) on the StudentGrade.subject_teacher

Example:

subject_teacher = <subject1> <subject2> 
selected: <subject1>

student = choices from <subject1>.students

I already tried looking on similar cases such as editing the ModelForm but I couldn't get the gist of it.

CodePudding user response:

If you want to use a model form that has a filtered queryset, you can do so like this:

# forms.py

class MyForm(forms.ModelForm):
   def __init__(self, *args, **kwargs):
      self.students = StudentProfile.objects.filter( # your filter )
      super(MyForm, self).__init__(*args, **kwargs)
      self.fields['students'].queryset = self.students

If you are adding a StudentGrade directly in the Django Admin then it won't know which subject_teacher you want and will show a <select> with all the options. You would need to specify the subject_teacher before the form is initiated for the filter to work the way you want.

  • Related