commit=False in Model save?

4,147 views
Skip to first unread message

Heleen

unread,
Jun 15, 2010, 3:23:35 AM6/15/10
to Django users
Hello,

I have a situation where I would like to do some validation on a many-
to-many field in a model before it is saved. When the validation fails
the model should not be saved and result in an appropriate error.
However to be able to do anything with a many-to-many field the
primary key of the model should be available, therefore it seems that
the model should be saved first.

In Forms there is the option to save with commit=False, but I could
not find anything similar to this for the Models save function.
Also, using a pre-save signal would not work, because the model is not
saved yet. A post-save signal doesn't work either because then the
model gets saved even in the cases that it shouldn't. Rewriting the
save function would be the best option, but because I cannot 'pre'-
save with commit=False this doesn't work either.

Could anyone tell me if there is such a function to achieve what I
need or if there is a better way of doing this?
Thanks very much!
Heleen

Heleen

unread,
Jun 15, 2010, 10:47:19 AM6/15/10
to Django users
Someone e-mailed me a reply, and I thought I'd make it public before I
reply.

What you could do is use manual transaction management and do
something like:

@transaction.commit_manually
def my_view(request):
...
try:
my_form.save()
except MyFormException:
# thrown when validation fails, etc.
transaction.rollback()
finally:
transaction.commit()

That should allow you to create the PKs and then get out of there if
there's a problem.

Heleen

unread,
Jun 15, 2010, 10:51:43 AM6/15/10
to Django users
Thanks to the 'unknown' user for the reply. This is probably what I'm
looking for. I think I have had a glance at it while searching the
Django Docs but I don't think I fully understood it. I do now and will
give it a go tomorrow morning!

Heleen

unread,
Jun 16, 2010, 5:18:39 AM6/16/10
to Django users
Today I'm a bit more awake than when I replied yesterday and I
realized that you're talking about views here.
What I mean however is that I would like to do validation in the model
class' save function in models.py.

I have tried to use this method on my save function though, but it
just gives me the following error:
Transaction managed block ended with pending COMMIT/ROLLBACK
I don't think it should be pending. My save function will eventually
commit or rollback and the error occurs in both cases. So either this
method doesn't work when used on a model class' save function, or
because it's not a view function, something else needs to happen as
well that I don't know of (in case of a rollback the function might
for example need to return an error of some kind).

I've also come across the problem that the 'through' table of my
ManyToManyField is not updated before commit. I call super(Model,
self).save(*args, **kwargs) at the start of def save(*args,
**kwargs):, but I get an empty list when after super-save I try to
retrieve the linked through instances, because they simply do not
exist yet.

Could anyone tell me if what I'm doing is the right way of approaching
it and how it should be done?
Thanks!
Reply all
Reply to author
Forward
0 new messages