form.save() fails silently - how to debug?

1,808 views
Skip to first unread message

Derek

unread,
Jul 26, 2012, 3:35:37 AM7/26/12
to django-users
I'd appreciate some help with the following problem, under Django 1.4

When running with the models, forms and view as described below, the data from the form is *not* saved into the model.

However, when using the test code (shown at the end) in a shell environment, the data *is* saved as expected.

How can I tell why the form data is not saved in the view?  It appears to "fail silently" (i.e. no errors reported) - but adding print statements into the code reveal that the correct data is available just before the .save() function.  Is there a preferred approach for debugging this type of situation?

Thanks
Derek


# models
class ClientFile(Model):
    id = AutoField(primary_key=True)
    description = CharField(unique=True, max_length=255)
    file = FileField(upload_to='client', storage=CLIENT_STORAGE)


class ClientData(Model):
    id = AutoField(primary_key=True)
    clientfile = ForeignKey(ClientFile)
    data_set = DictionaryField(blank=True, null=True)


# forms
class ClientDataForm(ModelForm):

    class Meta:
        abstract = True
        model = ClientData
        widgets = {
            'data_set': HiddenInput(),
            'clientfile': HiddenInput()
        }


class ClientDataFormLayout(ClientDataForm):
    label = CharField(max_length=255)
    top_left = CharField(max_length=255)
    bottom_right = CharField(max_length=255)

    def __init__(self, *args, **kwargs):
        super(ClientDataForm, self).__init__(*args, **kwargs)

    class Meta(ClientDataForm.Meta):
        pass

    def clean(self):
        cleaned = self.cleaned_data
        # copy for alteration
        cleaned_data = copy.deepcopy(self.cleaned_data)
        del cleaned_data['data_set']
        del cleaned_data['clientfile']
        cleaned['data_set'] = cleaned_data
        return cleaned


# view
    client_dataform_layout = ClientDataFormLayout()
    client = get_object_or_404(ClientFile, pk=1)
    initial = {'clientfile': client}
    if request.method == 'POST':
        formset = client_dataform_layout(request.POST, instance=client)
        if formset.is_valid():
            results = formset.save(commit=False)
            form_data = formset.cleaned_data  #  test only
            formset.save()
    else:
        formset = client_dataform_layout(instance=client, initial=initial)
    return render_to_response("clients/client_data.html",
                              locals(),
                              RequestContext(request))


# test code
formset = ClientDataFormLayout(data {'clientfile': 1, 'data_set': '',
                                     'top_left': 'AA', 'bottom_right': 'ZZ',
                                     'label': 'foobar'})
print formset.is_valid()
results = formset.save(commit=False)
formset.save()
cd = ClientData.objects.get(clientfile__pk=1)
print cd.data_set

Karl Sutt

unread,
Jul 26, 2012, 3:47:00 AM7/26/12
to django...@googlegroups.com
I think
results = formset.save(commit=False)
formset.save()
should be
results = formset.save(commit=False)
results.save() 

Tervitades/Regards
Karl Sutt



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Derek

unread,
Jul 26, 2012, 1:57:41 PM7/26/12
to django...@googlegroups.com
Thank you for the suggestion, but unfortunately that too does not work. 

I really need to find a way to get at the source of the problem; I would think an error message should be generated but none shows up...


On Thursday, July 26, 2012 9:47:00 AM UTC+2, Karl Sutt wrote:
I think
results = formset.save(commit=False)
formset.save()
should be
results = formset.save(commit=False)
results.save() 

Tervitades/Regards
Karl Sutt


To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.

Jirka Vejrazka

unread,
Jul 26, 2012, 3:32:30 PM7/26/12
to django...@googlegroups.com
> Thank you for the suggestion, but unfortunately that too does not work.
>
> I really need to find a way to get at the source of the problem; I would
> think an error message should be generated but none shows up...

Are you doing some magic in model's save() by any chance?

Jirka

Jirka Vejrazka

unread,
Jul 26, 2012, 3:35:28 PM7/26/12
to django...@googlegroups.com
Sorry, I should have read your code before answering.

I'm struggling to understand what you do in your clean() method. Are
you sure you're returning the right set of data?

Jirka

Derek

unread,
Jul 27, 2012, 3:25:34 AM7/27/12
to django...@googlegroups.com
The clean() method basically stores the non-model field data in the model's dictionary field.  If this method was faulty, then it would also cause problems in the test code.  As I said, when I print the data to console it looks OK.  I am still trying to find how and where the save() method indicates errors...?

Karen Tracey

unread,
Jul 27, 2012, 8:00:37 AM7/27/12
to django...@googlegroups.com
On Fri, Jul 27, 2012 at 3:25 AM, Derek <game...@gmail.com> wrote:
The clean() method basically stores the non-model field data in the model's dictionary field.  If this method was faulty, then it would also cause problems in the test code.  As I said, when I print the data to console it looks OK.  I am still trying to find how and where the save() method indicates errors...?

Model save() would indicate an error by raising an exception, see:

https://github.com/django/django/blob/master/django/db/models/base.py#L444

I would attack the problem you are seeing by tracing through what's actually happening using pdb.

Karen
--
http://tracey.org/kmt/

Derek

unread,
Jul 27, 2012, 9:46:01 AM7/27/12
to django...@googlegroups.com
Thanks Karen

I am not quite sure what you mean by "Model save() would indicate an error" - I am making a call to the form.save(), which in turn, I assume, should result in the data being saved to the model (although nothing gets saved in my case)?  No error is being raised that I can see.  

I have not used pdb before; I will need to look into how that works and how might help me.

On Friday, 27 July 2012 14:00:37 UTC+2, Karen Tracey wrote:

Dan Gentry

unread,
Jul 27, 2012, 10:36:57 AM7/27/12
to django...@googlegroups.com
I too am a little confused by the clean() method and the data_set field.  It seems that the data_set would contain a copy of the ID value for a change operation, and be None for an add.  What purpose does that serve?

Perhaps comment the clean() method just to see if the other fields can be saved.

Also, I concur with Karl's suggestion to use results.save()

Good luck!

Derek

unread,
Jul 29, 2012, 8:59:27 AM7/29/12
to django...@googlegroups.com
Just to follow up...

I have tried using pdb - but stepping into the Django code goes through hundreds of lines of records and, to be honest, its not clear at all what I should be looking for or where I would expect to see errors...  If there is any guidance in this respect, I would be happy to hear it.

As per Dan's suggestion, I have also tried stripping out all the non-model fields from the form, along with all the "funny" clean code (I now just have a straightforward return of the cleaned data). Again, no success: the cleaned data looks OK (in the print statement) but it is simply not saved.

Derek

unread,
Jul 29, 2012, 2:33:20 PM7/29/12
to django...@googlegroups.com
Finally (!) a  solution. 

Turns out the problem is in line 53 of the code I originally posted:
    formset = client_dataform_layout(request.POST, instance=client)
when I omit the ", instance=client" part, then all works as expected...

I do need to understand the reason why that was causing a "silent fail", but at least I can make progress now.

Thanks to all who made suggestions.
Reply all
Reply to author
Forward
0 new messages