MR: _manipulator_validate_FIELD() methods?

2 views
Skip to first unread message

Matthew Flanagan

unread,
May 4, 2006, 8:08:35 AM5/4/06
to django...@googlegroups.com
Hi

I've been porting a large application to MR since monday and have it
99% done except for a few issues. One of them is the
_manipulator_validate_FIELD(self, field_data, all_data) methods not
being call for my models. Is this intended behaviour?

I was able to turn some of the methods into regular validators,
however, with two others I need to check whether the manipulator is an
Add or a Change one and do things differently. If I turn these into
regular functions that I just add to the fields validator list how can
can I determine this?


cheer

matthew

Matthew Flanagan

unread,
May 6, 2006, 8:30:10 AM5/6/06
to django...@googlegroups.com

(I know it's bad form to reply to my own email's but...)

I just thought I should clarify what I was doing before with the
_manipulator_validate_FIELD() model methods, how I've translated them
to the latest post-MR trunk, and the problem I'm now facing.

in pre-MR I had a model with:

def _manipulator_validate_somefield(self, field_data, all_data);
...
if getattr(self, 'original_object', None):
# do something if we are changing the object
else:
# do something else if we are adding the object.

I originally did things this way rather than using a custom
manipulator so that I could just use the django admin and/or generic
views to add/change my model data and everything would just work...as
if by magic!

Over time many of my application views moved to using my own "generic"
views and the behaviour above still worked.

Since MR merged the _manipulator_validate_FIELD() methods stopped
working. The solution I came up with was to write custom manipulators
(which was what I was trying to avoid all along). My solution so far
is:

# this was _manipulator_validate_somefield()
def validateSomeField(manipulator, field_data, all_data):
if getattr(manipulator, 'original_object', None):
# do something if we are changing the object
else:
# do something else if we are adding the object.

class MyModelAddManipulator(MyModel.AddManipulator):
def __init__(self, follow=None):
MyModel.AddManipulator.__init__(self, follow=follow)
newfields = []
for field in self.fields:
if field.field_name == "somefield":
# want to insert our new validator before the last _curried one
field.validator_list.insert(-1, self.validateSomeField)
newfields.append(field)
self.fields = newfields

def validateSomeField(self, field_data, all_data):
validateSomeField(self, field_data, all_data)

class MyModelAddManipulator(MyModel.ChangeManipulator):
def __init__(self, obj_key, follow=None):
MyModel.ChangeManipulator.__init__(self, obj_key, follow=follow)
newfields = []
for field in self.fields:
if field.field_name == "somefield":
# want to insert our new validator before the last _curried one
field.validator_list.insert(-1, self.validateSomeField)
newfields.append(field)
self.fields = newfields

def validateSomeField(self, field_data, all_data):
validateSomeField(self, field_data, all_data)

This is all fine except you can no longer use generic views or django
admin to edit your model data as they will not use the new
manipulators. Which is where I've hit the problem that some of my apps
don't have their own views and I use the admin to edit them.

Here's the bit where I want my cake and eat it too: Can I make the
django admin app use my custom manipulators? If not then the immediate
benefits of django's admin app are lost for me.

matthew

Ivan Sagalaev

unread,
May 6, 2006, 9:35:22 AM5/6/06
to django...@googlegroups.com
Matthew Flanagan wrote:

>Since MR merged the _manipulator_validate_FIELD() methods stopped
>working. The solution I came up with was to write custom manipulators
>(which was what I was trying to avoid all along).
>

Can you assign those validators to the validator_list of a field right
in a model? I never had a chance to use _manipulator_validate_FIELD() so
I don't know if there is any difference.

Matthew Flanagan

unread,
May 6, 2006, 7:09:18 PM5/6/06
to django...@googlegroups.com

The validator functions assigned to a models validator_list only take
two arguments eg. isValidField(field_data, all_data). Where as they
_manipulator* ones looked like this _manipulator_validate_FIELD(self,
field_data, all_data), where 'self' was the manipulator instance. The
latter were automatically added to the model's manipulator in
pre-magic-removal.


matthew

Tom Tobin

unread,
Aug 8, 2006, 4:39:02 PM8/8/06
to django...@googlegroups.com

I know this is an old thread, but I just ran into the same issue on
trunk: I have no idea how to duplicate the _manipulator_validate_FIELD
behavior from pre-MR in order to access fields from the original
object in a validator. I can't find anything in the current docs or
in the source which might indicate how to do this; anyone have any
pointers? :-)

Tom Tobin

unread,
Aug 8, 2006, 9:24:19 PM8/8/06
to django...@googlegroups.com

Hooray! I think I've figured it out:

1) Define a custom manager for the model.
2) Hang a validator (the name can be arbitrary, i.e., it doesn't have
to start with _validator_ or somesuch) off of the custom manager.
3) In the validator_list for the field in question, point to the
custom manager instance's attribute of the validator.
4) Inside the validator, the values of the existing object can be
accessed through self.values()

This is probably expressed more clearly through code:

class FooManager(models.Manager):
def isSpamEggs(self, field_data, all_data):
existing_parrot_value = self.values()['parrot']
# do some validation stuff

class FooModel(models.Model):
objects = FooManager()
parrot = models.CharField(maxlength=50, validator_list=[objects.isSpamEggs])

Hopefully this will save someone else some head-desking; I'll see
about writing up a patch for the docs describing this (unless I
discover that I've been blind and this is, indeed, documented
somewhere). :-D

Tom Tobin

unread,
Aug 8, 2006, 9:29:38 PM8/8/06
to django...@googlegroups.com

Neeever mind, I'm a moron. I've had a *way* too long past couple of days. :p

::sigh::

mattim...@gmail.com

unread,
Aug 9, 2006, 1:36:10 AM8/9/06
to Django users
Tom,

Does the solution I posted [1] earlier in this thread not work for you?


[1] http://groups.google.com/group/django-users/msg/a76be4c94631ec80

matthew

Tom Tobin

unread,
Aug 9, 2006, 1:46:01 AM8/9/06
to django...@googlegroups.com

Getting these manipulator-aware validators working in the admin is
exactly the issue I want to solve; I came up with a proposal to
reinstate similar behavior to pre-MR-removal Django and posted it to
Django-dev. I now have both mentioned potential solutions working;
it's just a matter of deciding which one I prefer (or, quite likely,
having someone else smarter than me hit me with a stick and point out
a superior way of doing it). ;-)

Reply all
Reply to author
Forward
0 new messages