Can't assign field in form_valid method, Not null constraint Error

Viewed 101

I'm getting the error:

IntegrityError at /projects/1/issues/new/ NOT NULL constraint failed: issues_issue.project_id Request Method: POST Request URL: http://127.0.0.1:8000/projects/1/issues/new/ Django Version: 3.0.3 Exception Type: IntegrityError Exception Value:
NOT NULL constraint failed: issues_issue.project_id

Issues have a Foreign key to project, and I assign it in the form_valid method, I do the same with the user and that works fine

CreateView in views.py:

class IssueCreateView(LoginRequiredMixin, CreateView):
        model = Issue
        fields = ['title', 'details', 'priority', 'status', 'estimated_work_hours', 'loaded_work_hours']

        def form_valid(self, form):
            form.instance.project = get_object_or_404(Project, pk=self.kwargs['project_id'])
            print(form.instance.project)
            form.instance.creator = self.request.user
            return super().form_valid(form)

The line print(form.instance.project) prints the correct project, so that's working.

models.py:

class Issue(models.Model):
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    creator = models.ForeignKey(User, related_name="%(class)ss_created", on_delete=models.CASCADE)
    ...
    ...

Why can I assign the creator field to an user in the form_valid method but when I do the same thing for the Project field it doesn't work, I don't understand it.

Does anyone know what could be the problem?

Thanks

1 Answers

Your form does not honor project and creator in your instance. Its pretty much the same if you would have just set form.instance.xyz = self.request.user

So you have to add project and creator to your fields.

If you are using {{ form.as_p }} you will have the next problem, that these fields are included in your form. There are multiple ways to handle that. One would be to just hide them i a custom form. The final result would be:

from django import forms

class IssueForm(forms.ModelForm):
    class Meta:
        model = Issue
        fields = ['project', 'creator', 'title', 'details', 'priority', 'status', 'estimated_work_hours', 'loaded_work_hours']
        widgets = {
            'project': forms.HiddenInput(),
            'creator': forms.HiddenInput(),
        }

class IssueCreateView(LoginRequiredMixin, CreateView):
    model = Issue
    form_class = IssueForm

    def form_valid(self, form):
        form.instance.project = get_object_or_404(Project, pk=self.kwargs['project_id'])
        form.instance.creator = self.request.user
        return super().form_valid(form)
Related