Re: __init__() takes at least 2 arguments (1 given) When Migrating with Custom Fields

212 views
Skip to first unread message

Andrew Godwin

unread,
Jul 25, 2012, 6:03:36 AM7/25/12
to south...@googlegroups.com

> any clues ?
>
>

Your custom field is expecting a default_callable argument which South
isn't providing (as it's not frozen, and being a callable, probably
can't be). There's no easy fix to this - providing callables as
arguments to fields is always annoyingly non-portable.

Andrew

Fady Kamal

unread,
Jul 25, 2012, 9:20:03 AM7/25/12
to south...@googlegroups.com
yes i discovered that recently from the tickets opened, but how can i fix such a problem, the hard way ?

Andrew Godwin

unread,
Jul 25, 2012, 10:57:39 AM7/25/12
to south...@googlegroups.com
On 25/07/12 14:20, Fady Kamal wrote:
> yes i discovered that recently from the tickets opened, but how can i
> fix such a problem, the hard way ?

Well, there's no "hard way", it just means you need to write a more
portable custom field. I'm afraid South can't magically solve the
problem of serialising fields at this point.

Andrew

Martin Maney

unread,
Jul 27, 2012, 12:46:34 PM7/27/12
to south...@googlegroups.com
On Wed, Jul 25, 2012 at 02:17:30AM -0700, Fady Kamal wrote:
> class DependentIntegerField(models.IntegerField):
> def __init__(self, default_callable, *args, **kwargs):
> self.default_callable = default_callable
> super(DependentIntegerField, self).__init__(*args, **kwargs)
>
> def pre_save(self, model_instance, add):
> if not add:
> return super(DependentIntegerField, self).pre_save(model_instance, add)
> return self.default_callable(model_instance)

> add_introspection_rules([
> (
> [Level], # Class(es) these apply to
> [], # Positional arguments (not used)
> { # Keyword argument
> "threshold": ["threshold", {}],
> },
> ),
> ], ["^shoghlanah\.models\.DependentIntegerField"])

The first problem I noticed was that you have the class the custome
field is used in [Level] where what should be there is
[DependentIntegerField]. Yes, it is a bit of seeming repetition, and the
example in the docs muddies things as much as it clarifies them. (1)

The problem with the unfreezable callable is easily fixed as far as
making it work with schema changes: just make it a keyword arg that
behaves sanely when not given (default None and only call it if not
None would be obvious). This may need some manual intervention when
actually creating instances in a data migration, but that I can see no
way around that unless you do something cumbersome like making a
trivial derived class (that needs to be registered, but they'll all be
trivial registrations at least) for each different default_callable.
BTW, surely that needs a better name?

Also BTW: for some reason your message all came through double spaced,
which made it harder to read the code especially. Here's what it
looked like (quoted for reply):

> class Level(models.Model):
>
> group = models.ForeignKey(Level_Group)
>
> number = models.IntegerField(unique=True)#null=True, blank=True

The line wrapping is probably mutt's fault, but the vertical spacing
isn't something it causes. Maybe you already noticed this and fixed
it, I'm replying to the original to avoid deeply-nested quotations even
though I have skimmed through the replies already.



1) Andy: I think it would go far if the example of rules included its
use in add_introspection rules rather than just being the rules
detached from the regexp - a complete example instead of the fragment.
My first thought would be to make it "this is how we'd define Django's
ForeignKey if it were a new custom field".

Wishlist: this has got me thinking about the non-DRY character of this
stuff. Oh, I know, in the builtins you use one regexp to catch all the
Django standard field types, but I can't see why you need that (hence
why there's this confusing thing that people have to struggle to get
right). Yes, yes, checking which models are safe to introspect, but
what if instead of the regexp silliness each registered rule
introspected its class list and extracted the exact path name, same as
the way the name that gets checked with the regexps is done. And then
you use that to build a path: rule distionary and do a single
dictionary lookup rather than regexp check to see if it's okay and
then... hmmm, what does it do now, since there's no direct connection
from regexp ro rule?

Yes, there's still use for an ignore list - not sure if that would be
just to weed out the lookup failures that are ignored or if that has to
come first so that it can mask already registered field classes. That
latter sounds pretty silly, but maybe it has some vital use I can't
imagine.

If this all sounds sane maybe I can find the time to poke at the code,
though the builtin setup stuff still doesn't quite make perfect sense
to me, so that might lead to more annoying questions. :-/

--
Obscurity is a far great threat to authors and creative artists
than piracy. -- Tim O'Reilly

Fady Kamal

unread,
Aug 6, 2012, 7:09:25 AM8/6/12
to south...@googlegroups.com, ma...@two14.net
actually i needed this model to automate values for the threshold attribute so i used the dependent integer field, so i changed the approach and solved it using the save method, anyways thanks for help
Reply all
Reply to author
Forward
0 new messages