I have this form
class PostCreationForm(forms.ModelForm):
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
and I'm trying to unit test it with this test
class PostCreationByFormTestCase(TestCase):
def __init__(self, *args, **kwargs):
super(PostCreationByFormTestCase, self).__init__(*args, **kwargs)
self.CustomUser = get_user_model()
def setUp(self):
self.credentials = {
'username': 'john_smith',
'password': 'St0ngPassw0rd'
}
self.user = self.CustomUser.objects.create(
username=self.credentials['username'],
email='[email protected]',
password=self.credentials['password'],
first_name='John',
last_name='Smith'
)
def test_simple_form(self):
form_data = {
'author': self.user,
'title': 'Simple Post',
'description': 'very good description',
}
form = PostCreationForm(form_data)
self.assertTrue(form.is_valid)
post = form.save()
the assert passes, but the form.save()
produces
django.db.utils.IntegrityError: null value in column "author_id" violates not-null constraint
I tried changing the form to
class PostCreationForm(forms.ModelForm):
def form_valid(self, form):
if not form.instance.author:
form.instance.author = self.request.user
return super().form_valid(form)
but it still does not work. I saw this as a recommended way to assign field to object if I don't want to take it as an input from the user as in this case where I want the author of the post to be the current user. How should I fix that in order to be able to test the form?
When checking whether a form is valid you need to call the method
is_valid
, it is not a property. Changingform.is_valid
toform.is_valid()
will work.form_valid()
however will not be called when you check forform.is_valid()
, so you probably want to use theclean
methods. An untested example: