2

I have a form including several fields. Let's say one of them is "subjects", a multiple choice selection field, and the other one is "main_subject", a single choice selection field. How should I code the views.py file in order to automatically select a subject in the "subjects" one, if the corresponding "main_subject" is selected? (I do not want to save a main subject for a student if it isn't included as one of his subjects).

models.py

class Subject(models.Model):
    subject=models.CharField(primary_key=True, max_length=100)

class Student(models.Model):
    name=models.CharField(primary_key=True, max_length=100)
    main_subject=models.ForeignKey(Subject, on_delete=models.SET_NULL, null=True)

class StudentSubject(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.ForeignKey(Student, on_delete=models.CASCADE)
    subject = models.ForeignKey(Discipline, on_delete=models.CASCADE)
    class Meta:
        constraints = [models.UniqueConstraint(fields=['name ', 'subject '], name='uniqueStudentSubject')]

forms.py

class NewStudentForm(forms.ModelForm):
    class Meta:
        model=Student
        fields=['name', 'main_subject']
        widgets={'name': forms.TextInput(), 'main_subject': forms.Select()}
    subjects = forms.ModelMultipleChoiceField(
                        widget=forms.CheckboxSelectMultiple(),
                        queryset=Subject.objects.all(),
                        required=False
                        )

views.py

def new_student(request):
    if request.method == 'POST':
         form = NewStudentForm(request.POST)
    if form.is_valid():
         form.save(commit=True)
         for stu in form.cleaned_data['subjects']:
                StudentSubject.objects.create(
                    name=Project.objects.get(pk=request.POST['name']),
                    subject=Subject.objects.get(pk=stu)
                    )
         # SOMETHING ELSE......... #

Lokicor
  • 117
  • 3
  • 11
  • 2
    If you want an interactive selection without save, you should get your hands dirty with some frontend js code to listen selection change event and fire an event accordingly. – Deniz Feb 02 '21 at 13:39
  • Thanks for your answer. What if I didn't need an interactive selection? Instead, how could it be done just to save the main subject as a selected subject once the user submits the form? – Lokicor Feb 04 '21 at 09:24
  • In addition, where should I place the js code if I wanted the interactive selection? This question comes to my mind since the HTML code includes the {{ form }} label, and I don't know how to reference its inputs. Should it be something like {{ form.main_subject }} ? Thanks again. – Lokicor Feb 04 '21 at 09:29

1 Answers1

1

I think it is done by JavaScript as @Deniz said. I did not know JS until a few hours ago, so I am not sure this is the best solution, but for me, it works. It is just a matter of adding the following to the html file (obviously considering de corresponding IDs on your project for each element):

<script type="text/javascript">
        var main_subject_list = document.getElementById("id_main_subject");
        main_subject_list.addEventListener("change", function() {
            for (var i = 0; i < main_subject_list.options.length; i++) {
                var option = main_subject_list.options[i];
                if (option.selected) {
                    var checkbox_to_select = document.getElementById("id_subject_" + (i - 1)).click();
                }
            }
        });

</script>
Lokicor
  • 117
  • 3
  • 11