How can I populate a model with non-form data?

I have Student, Class and StudentClass models. I would like a student to be able to join a new class by inputting the class_code into a form. To join a class the user’s student_id and the class_code is saved to the StudentClass model. The student_id isn’t a form field so should be obtained by querying the Student model with the logged-in user’s username and returning the student_id.
models.py:

class StudentClass(models.Model):
    class Meta:
        unique_together = (('class_code', 'student_id'),)
    class_code = models.ForeignKey(Class, on_delete=models.CASCADE)
    student_id = models.ForeignKey(Student, on_delete=models.CASCADE)

forms.py:

class JoinClassForm(forms.ModelForm):
    class Meta:
        model = StudentClass
        fields = ['class_code']

views.py

@login_required
def join_class(request):
    if request.method == "POST":
        joinclass_form = JoinClassForm(request.POST or None)
        if joinclass_form.is_valid():
            formclass_code = joinclass_form.data.get('class_code')
            if Class.objects.filter(class_code=formclass_code).exists():
                joinclass_form.save(commit=False)
                joinclass_form.student_id=              
                Student.objects.filter(username=request.user.username).values_list('student_id', flat=True)
                joinclass_form.save()
                return redirect('assignments')
            else:
                messages.success(request, ("This class doesn't exist!"))
    else:
        joinclass_form = JoinClassForm
    return render(request, 'join_class.html', {'joinclass_form': joinclass_form})

I’ve tried using a hidden_field for student_id, excluding student_id from the form fields and saving as commit=False, and I’ve gotten the same error: IntegrityError Not NULL constraint failed. Is there an error in my code that I have missed or am I using the wrong method? Thanks in advance :slight_smile:

Edit: There is a copy-paste error in the views.py code since I couldn’t fit the entire line in one line

You’re trying to add this data to the form rather than to the model being created from the form.

Once a form has been submitted, there’s usually very little value in trying to add or change data within the form.

I see where you’re trying to save the form using the commit=False parameter, but you’re not saving a reference to the object that the save function is creating.

Review the docs and the example at Creating forms from models | Django documentation | Django.

1 Like

Thankyou this was really helpful! :))