Django – issue with Not Null constraint

Question:

Hi in my program I keep receiving the above exception and am unsure why. The issue happens when my requestLessons_view method tries to save the form.

Views.py

def requestLessons_view(request):
    if request.method == 'POST':
        form = RequestLessonsForm(request.POST)
        if form.is_valid()  & request.user.is_authenticated:
            user = request.user
            form.save(user)
            return redirect('login')
    else:
        form = RequestLessonsForm()
    return render(request, 'RequestLessonsPage.html', {'form': form})

forms.py

class RequestLessonsForm(forms.ModelForm):
     class Meta:
        model = Request
        fields = ['availability', 'num_of_lessons', 'interval_between_lessons', 'duration_of_lesson','further_information']
        widgets = {'further_information' : forms.Textarea()}

        def save(self, user):
             super().save(commit=False)
             request = Request.objects.create(
                student = user,
                availability=self.cleaned_data.get('availability'),
                num_of_lessons=self.cleaned_data.get('num_of_lessons'),
                interval_between_lessons=self.cleaned_data.get('interval_between_lessons'),
                duration_of_lesson=self.cleaned_data.get('duration_of_lesson'),
                further_information=self.cleaned_data.get('further_information'),

            )
             return request

The error I receive is:
IntegrityError at /request_lessons/
NOT NULL constraint failed: lessons_request.student_id

Asked By: Fazza Bajwa

||

Answers:

Your .save() method is defined on the Meta class, not the form, hence the error. I would advise to let the model form handle the logic: a ModelForm can be used both to create and update the items, so by doing the save logic yourself, you basically make the form less effective. You can rewrite this to:

class RequestLessonsForm(forms.ModelForm):
    class Meta:
        model = Request
        fields = [
            'availability',
            'num_of_lessons',
            'interval_between_lessons',
            'duration_of_lesson',
            'further_information',
        ]
        widgets = {'further_information': forms.Textarea}

    def save(self, user, *args, **kwargs):
        self.instance.student = user
        return super().save(*args, **kwargs)

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


Note: You can limit views to a view to authenticated users with the
@login_required decorator [Django-doc].

Answered By: Willem Van Onsem
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.