ModelForm.is_valid() doesn't work the first time but does the second

1,323 views
Skip to first unread message

Michael Molloy

unread,
Jan 2, 2016, 9:18:01 PM1/2/16
to Django users
This is running in Openshift with Python 3.3 and Django 1.8.4

Here's my model:

class Users(models.Model):
    first_nm
= models.CharField('First Name', max_length=100)
    last_nm
= models.CharField('Last Name', max_length=100)
    email
= models.CharField('Email Address', max_length=200, unique=True)

Here's my form:

class UsersForm(forms.ModelForm):
   
class Meta:
        model
= Users
        fields
= ['first_nm', 'last_nm', 'email']


When I run the shell inside Openshift, this is what happens:

Python 3.3.2 (default, Mar 20 2014, 20:25:51) 

[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux

Type "help", "copyright", "credits" or "license" for more information.

(InteractiveConsole)


>>> from django.conf import settings

>>> from package.forms import UsersForm

>>> from package.models import Users


>>> u = Users()

>>> u.first_nm = 'First'

>>> u.last_nm = 'Last'

>>> u.email = 'em...@email.com'

>>> uf = UsersForm(u)

>>> uf.is_bound

True

>>> uf.is_valid

<bound method UsersForm.is_valid of <UsersForm bound=True, valid=Unknown, fields=(first_nm;last_nm;email)>>


>>> uf.save()


Traceback (most recent call last):

  File "<console>", line 1, in <module>

  File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib/python3.3/site-packages/Django-1.8.4-py3.3.egg/django/forms/models.py", line 463, in save

    construct=False)

  File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib/python3.3/site-packages/Django-1.8.4-py3.3.egg/django/forms/models.py", line 84, in save_instance

    if form.errors:

  File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib/python3.3/site-packages/Django-1.8.4-py3.3.egg/django/forms/forms.py", line 176, in errors

    self.full_clean()

  File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib/python3.3/site-packages/Django-1.8.4-py3.3.egg/django/forms/forms.py", line 392, in full_clean

    self._clean_fields()

  File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib/python3.3/site-packages/Django-1.8.4-py3.3.egg/django/forms/forms.py", line 401, in _clean_fields

    value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))

  File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib/python3.3/site-packages/Django-1.8.4-py3.3.egg/django/forms/widgets.py", line 223, in value_from_datadict

    return data.get(name, None)

AttributeError: 'Users' object has no attribute 'get'


>>> uf.save()

<Users: Users object>


First, why does uf.is_valid() return 


<bound method UsersForm.is_valid of <UsersForm bound=True, valid=Unknown, fields=(first_nm;last_nm;email)>>


the first time I call it, but on subsequent calls, uf.is_valid() returns True?


Second, why does uf.save() return that stacktrace the first time I call it, but the second time I call it, the object saves? 


Third, even though the Users object saves, the only value in the database for that row is the primary key. Neither the names nor the email field is saved.



I'm working through the Django Unchained book, and I'm also looking at the Django tutorial on djangoproject.com, and it looks to me like I'm doing everything that I'm supposed to, but obviously I'm missing something.


--Michael



Sergiy Khohlov

unread,
Jan 2, 2016, 10:48:39 PM1/2/16
to django-users

Is_valid is working. You have
problem with save. Check database setting.

3 січ. 2016 04:18 "Michael Molloy" <Ukal...@gmail.com> пише:
>ve

> --
> You received this message because you are subscribed to the Google Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
> To post to this group, send email to django...@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/dd08dc98-e3af-49c8-b549-c5dc4e72d3d6%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Michael Molloy

unread,
Jan 2, 2016, 10:52:53 PM1/2/16
to Django users
I'm not sure what could be wrong with the database settings. If I just create an instance of the model and save it, it saves to the database:

>>> u.email = 'jo...@test.com'

>>> u.save()


--M

> To unsubscribe from this group and stop receiving emails from it, send an email to django-user...@googlegroups.com.
> To post to this group, send email to djang...@googlegroups.com.

Sergiy Khohlov

unread,
Jan 2, 2016, 11:13:58 PM1/2/16
to django-users

Sorry I missed. You have valid unknown at the start. Why are you not used django user model and author? Study purpose ,?

3 січ. 2016 05:53 "Michael Molloy" <ukal...@gmail.com> пише:
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.

Vijay Khemlani

unread,
Jan 2, 2016, 11:16:38 PM1/2/16
to django...@googlegroups.com
"First, why does uf.is_valid() return"

because you called "uf.is_valid" (note the lack of parenthesis), that's just a reference to the method and does not call it.

"Second, why does uf.save() return that stacktrace the first time I call it, but the second time I call it, the object saves? "

As far as I know ModelForm subclasses take a dictionary as a first parameter, not the object itself, you would need to do something like this:

uf = UsersForm(instance=u)

I don't know why it works the second time (if it does indeed work)


Michael Molloy

unread,
Jan 2, 2016, 11:21:39 PM1/2/16
to django...@googlegroups.com
Not studying; I’m working on a website that will be used to register people for an event, but it is my first Django site. 

I’m aware that I can add to the existing user model, and I may. However, this is just my first attempt to create a model and form and save data to the database. I don’t think that whatever I’m doing wrong will be limited to this model.

I’m missing something.

—M

You received this message because you are subscribed to a topic in the Google Groups "Django users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-users/TT1dJhsDpSY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-users...@googlegroups.com.

To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

Michael Molloy

unread,
Jan 2, 2016, 11:29:58 PM1/2/16
to Django users
Thank you for your help. I apologize for the typo, but I am calling is_valid() with the parenthesis:


>>> uf = UsersForm(u)


>>> uf.is_valid()


Traceback (most recent call last):

 File "<console>", line 1, in <module>

 File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib64/python3.3/site-packages/django/forms/forms.py", line 184, in is_valid

   return self.is_bound and not self.errors

 File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib64/python3.3/site-packages/django/forms/forms.py", line 176, in errors

   self.full_clean()

 File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib64/python3.3/site-packages/django/forms/forms.py", line 392, in full_clean

   self._clean_fields()

 File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib64/python3.3/site-packages/django/forms/forms.py", line 401, in _clean_fields

   value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))

 File "/var/lib/openshift/5678c24389f5cff0330001cd/python/virtenv/venv/lib64/python3.3/site-packages/django/forms/widgets.py", line 223, in value_from_datadict


    return data.get(name, None)


AttributeError: 'Users' object has no attribute 'get'



>>> uf.is_valid()


True



As for creating the form instance with the instance keyword, I tried that first as I saw it in the materials I was reading, but it doesn't work. Note the code below. is_bound = False if I use instance=u. If I just pass the Users instance without the 'instance' keyword, is_bound returns True.

>>> u = Users()


>>> u.email = 'je...@home.net'


>>> uf = UsersForm(u)


>>> uf.is_bound


True


>>> uf = UsersForm(instance=u)


>>> uf.is_bound


False



--M

Vijay Khemlani

unread,
Jan 3, 2016, 8:53:02 AM1/3/16
to django...@googlegroups.com
Well, it's not supposed to be bound if you don't pass any data to it

the "instance" in the ModelForm (if i remember correctly) just sets the initial values for the fields when you render the form in HTML and modifies that instance when you call "save" on the ModelForm.

knbk

unread,
Jan 3, 2016, 9:05:21 AM1/3/16
to Django users

>>> uf = UsersForm(u)

Here you are passing the user instance as if it were the POST data. The form expects a dictionary or None as the first argument. `form.is_bound` simply checks `data is not None`, which is True in this case.

If you want a bound form, you should pass a dictionary with the appropriate values as the first argument, and pass the user instance as the `instance=` argument. Forms are meant to handle user input in a POST request -- that's why it only accepts a dictionary such as request.POST as the input data.

Michael Molloy

unread,
Jan 3, 2016, 5:05:03 PM1/3/16
to Django users
That makes sense. Thank you.

--M

Michael Molloy

unread,
Jan 3, 2016, 5:05:29 PM1/3/16
to Django users
Thank you for your help.

--M
Reply all
Reply to author
Forward
0 new messages