Pablo
Pablo

Reputation: 13590

Is this an error in the documentation?

Today I started reading the documentation for django.forms. The API seems easy to use and I started experimenting with it. Then I started experimenting with django.forms.ModelForm but I cannot really see where I went wrong.

My problem starts here: the save method when creating a form with an instance.

My model is

class Process(models.Model):
    key         = models.CharField(max_length=32, default="")
    name        = models.CharField(max_length=30)
    path        = models.CharField(max_length=215)
    author      = models.CharField(max_length=100)
    canparse    = models.NullBooleanField(default=False)
    last_exec   = models.DateTimeField(null = True)
    last_stop   = models.DateTimeField(null = True)
    last_change = models.DateTimeField(null = True, auto_now=True)

and my form is

class ProcessForm(ModelForm):
    class Meta:
        model  = Process
        fields = ('name', 'path', 'author')

I only wanted the name, path and author fields since the other ones are automatically set when saving the model. Anyway, in my test database I already have entries and I've chosen one whose fields are all set and valid.

In the documentation you can read:

# Create a form to edit an existing Article.
>>> a = Article.objects.get(pk=1)
>>> f = ArticleForm(instance=a)
>>> f.save()

Very well, I wanted to do the same with my own code:

>>> from remusdb.models import Process
>>> from monitor.forms import ProcessForm
>>> 
>>> proc = Process.objects.get(name="christ")
>>> pf = ProcessForm(instance=proc)
>>> pf.save()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/shaoran/devpython/lib/python2.6/site-packages/django/forms/models.py", line 364, in save
    fail_message, commit, construct=False)
  File "/home/shaoran/devpython/lib/python2.6/site-packages/django/forms/models.py", line 87, in save_instance
    save_m2m()
  File "/home/shaoran/devpython/lib/python2.6/site-packages/django/forms/models.py", line 78, in save_m2m
    cleaned_data = form.cleaned_data
AttributeError: 'ProcessForm' object has no attribute 'cleaned_data'
>>> pf.is_bound
False
>>> pf.is_valid()
False

Even though proc is a valid Process object the form object doesn't seem to agree with me. If I do as the next example

>>> post = { "name": "blabla", "path": "/somewhere", "author": "me" }
>>> pf = ProcessForm(post, instance=proc)
>>> pf.is_bound
True
>>> pf.is_valid()
True
>>> pf.cleaned_data
{'path': u'/somewhere', 'name': u'blabla', 'author': u'me'}

then it works like in third example of the documentation.

Am I missing something or is there an error in the documentation? Or is my Model code somewhat wrong?

This is the content of proc

proc.dict {'name': u'christ', 'last_stop': datetime.datetime(2012, 10, 5, 16, 49, 13, 630040, tzinfo=), 'author': u'unkown', '_state': , 'canparse': False, 'last_exec': datetime.datetime(2012, 10, 5, 16, 49, 8, 545626, tzinfo=), 'key': u'aed72c9d46d2318b99ffba930a110610', 'path': u'/home/shaoran/projects/cascade/remusdb/test/samples/christ.cnf', 'last_change': datetime.datetime(2012, 10, 5, 16, 49, 13, 631764, tzinfo=), 'id': 5}

Upvotes: 1

Views: 124

Answers (1)

Burhan Khalid
Burhan Khalid

Reputation: 174698

The first argument to the form class is a dictionary that contains values that you want the form to validate.

Since you never pass these values in, the form cannot validate any input; which is why cleaned_data is none. Since .save() triggers form and model validation, the form validation fails.

You'll notice the form actually has no data:

af.data will be {} (empty dict) af.is_bound will be False (as you haven't bound the form to any data)

Since there is no data, validation fails. The error is a bit misleading. If you pass in an empty dict:

af = ArticleForm({},instance=a)
af.save()

You'll get a more appropriate error:

ValueError: The Article could not be changed because the data didn't validate.

Upvotes: 1

Related Questions