phil0s0pher
phil0s0pher

Reputation: 555

Setting model user to request.user with CreateView in Django returns "null value in column "author_id" error

I have a CreateView operating on a ModelForm, which subclasses the model Item. Item.author = ForeignKey(User,on_delete=models.CASCADE,)

In the CreateView, the user fills in most of the form, but I want Item.author to be set to request.user. Whenever I do that, using form_valid() to set form.instance.author = self.request.user, I get an error back, saying "null value in column "author_id" violates not-null constraint"

I've tried removing 'author' as a field to edit from the form.py.

This is what I am trying to replicate: https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-editing/#models-and-request-user

Model.py


    class Item(models.Model):


    # SOME OTHER FIELDS WHICH RENDER AND SAVE FINE

    author = models.ForeignKey(User,
                                on_delete=models.CASCADE,

            def get_absolute_url(self):
               return reverse('item_detail',args=[str(self.id)])
                               )

forms.py

    class SubmitItemForm(forms.ModelForm):

    class Meta():
        model = Item
        fields = ('link','title','excerpt','type','author')


    def __init__(self, *args, **kwargs):
        super(SubmitItemForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.form_id = 'submit_item'
        self.helper.form_class = 'submit'
        self.helper.form_method = 'post'
        self.helper.form_action = 'item_detail'

        self.helper.add_input(Submit('submit', 'Submit'))

views.py

    class SubmitItem(LoginRequiredMixin, generic.CreateView):
    login_url = '/login/'
    redirect_field_name = 'item_detail.html'
    form_class = SubmitItemForm
    model = Item

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

    def form_invalid(self, form):
        response = super().form_invalid(form)
        return response

I'm expecting the form to save to the database, and redirect the browser to the saved data using get_absolute_url() method described on the Item model.

Upvotes: 0

Views: 1056

Answers (2)

phil0s0pher
phil0s0pher

Reputation: 555

For anyone struggling with this same problem - here's how I got it to work. I didn't include in the code above (!!!) that I have a def clean(self) method on the model.

'''python def clean(self): all_clean_data = super().clean() self.save()

I removed this line (as I believe this was from a previous iteration, and form_valid() takes care of validation(?) and applied Anjaneyulu's fix above, and now the model saves correctly.

Upvotes: 0

anjaneyulubatta505
anjaneyulubatta505

Reputation: 11675

You can change your form_valid method like below

    def form_valid(self, form):
        form.instance.author_id = self.request.user.pk
        return super().form_valid(form)

Upvotes: 1

Related Questions