On Wed, Aug 12, 2009 at 9:24 AM, David<da...@davidfindlay.org> wrote:
>
> After being unable to get any advice or further information via
> google, #django or the users' mailing list, I opened
> http://code.djangoproject.com/ticket/11652 regarding the admin
> interface not preventing simultaneous editing of the same record (or
> at least not providing that as an option). I guess this is not a
> typical usage scenario, but for my use case I would like to implement
> it if at all possible.

You are correct that django.contrib.admin doesn't currently provide
protection against simultaneous edits.

I can't say this is a problem I've experienced myself. The sites I've
dealt with have fairly low traffic admin sites, or only a small number
of editors. However, I agree that it would be nice if this sort of
protection were to be 'baked in' - preferably at the ModelForm level,
if that's not possible, then as a specific extension to admin.

> My first thought was to try grab a JSON representation of the original
> record in an override of ModelAdmin.change_view; I thought I might be
> able to save this via extra_context and somehow get it back when
> change_view is called the second time for the HTTP POST of the
> modified record. I was hoping to then compare that saved JSON
> representation of the original record with the JSON representation of
> the record as it exists in the database on that POST call; if they
> differed then someone must have changed the record in the meantime and
> so I could generate an error message.
>
> I realized if I added an AutoField data to the record and saved that
> instead, then that would be a lot cheaper to save and compare, but I
> still don't know how to save that information.

There are any number of ways to solve this problem by adding a field
to the model (autofield with an 'edit number', timestamp tracking last
edit time etc). However, these aren't really candidates for a general
solution.

> Is there a way to save information in the session and get it back on
> subsequent calls?

Well... yes... that's what a session is :-)

That said, I'm not sure the session is the right place for this. It
really needs to be stored per form - consider the case of a single
user with multiple tabs open in the admin interface.

> Using an AutoField date it would probably be sufficient to just know
> when the original GET of the record happened for the user to start
> changing it. Is there a way to find that out?
>
> If anyone has any pointers or advice I'd be most grateful.

A few random thoughts:

Django's forms already have some functionality that is tangentially
related. If you have fields with callable default values, Django will
insert a hidden field into the form to contain the initial value. This
is required because the value of the callable at time of POST
processing may not be the same as the value of the callable when the
form is originally displayed. This isn't exactly the same scenario,
but it may give you some ideas to see how this could be implemented
for the larger problem.

Another piece of related work - In the run up to v1.1, a few changes
were made to avoid modification issues in FormSets. #10922 described a
problem - again, it's not quite the same problem, but it's vaguely
related, and may provide some illumination on ways to tackle the
problem.

A related thought - prior to v1.0, Django's login form would store
POST data in a pickle  in a hidden field if the login session data
expired. This was removed from the login form because an attack vector
was demonstrated using this POST data, but as a general approach for
checking for modifications, I suspect it could be used here. A hidden
field on a form that contains a pickle of the original object data
could be added to the field on the original form render; on POST, the
pickle could be decompiled to give the original field values for
comparison.

A somewhat simpler approach would be to use a checksum - calculate an
md5/sha hash of the original object data and include it in a hidden
field. On submit, recompute the hash based on current values. If the
has changed, there have been modifications. I suspect that this would
be easier to implement, but would give you slightly less feedback - it
would be able to tell you that the object has been modified, but
wouldn't be able to tell you the nature of the modifications.

Yet another approach would be to only make this 'feature' available to
those objects that support it. That is, define a
'ConcurrentModificationField' as an extension of AutoField that you
can put on a model; this field would include a default form
implementation that does the appropriate validation. This isn't a
complete solution, but it could be implemented without any
modifications to Django itself.

If this is a problem that interests you, then I encourage you to dig
around. Developing the code to implement this fix will certainly give
you a very good grounding in the internals of Django's form
infrastructure. If you can find a clean way to implement this
functionality, then we are certainly interested in integrating this
into the Django core.

Yours,
Russ Magee %-)

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

Reply via email to