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.