0

Here is the deal. It worked, when done this way:

class UUIDField(CharField):

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = kwargs.get('max_length', 22 )
        # kwargs['blank'] = True
        kwargs['default'] = lambda: uuid.uuid1().bytes.encode('base64').rstrip('=\n').replace('/', '_')
        CharField.__init__(self, *args, **kwargs)

class UUIDModel(models.Model):

    uuid = UUIDField(primary_key=True, max_length=22, editable=False)

Well as you may understand, the rest of the models inherit UUIDModel and everyone lives happily ever after. The problem is, that the built in Django migrations facilities (and South for that matter) don't go well with lambdas. Here is my take on trying to work around the lambda:

class UUIDField(CharField):

    def _gen_uuid(self):
      return uuid.uuid1().bytes.encode('base64').rstrip('=\n').replace('/', '_')

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = kwargs.get('max_length', 22 )
        # kwargs['blank'] = True
        kwargs['default'] = self._gen_uuid()
        CharField.__init__(self, *args, **kwargs)

Seems legit, but now the models get overwritten, that is the UUID doesn't change and every new model gets written to the same pk. As result I can't create more than one instance of anything. Where I've gone wrong? What the lambda does, my code does not? And most importantly, how it could be fixed?

wswld
  • 1,218
  • 15
  • 32
  • Seems like you *have* fixed it, by using the lambda. What's wrong with it? – Daniel Roseman Jul 23 '14 at 08:22
  • 1
    First to note: lambda statement generates function object, so in your first code `kwargs['default']` is a function object (callable), while in your second example you assign function call `self._gen_uuid()`, which means that `kwargs['default']` is a value, not a function object. That is difference between your examples. And thats why you get same uuid for every instance. As for your original problem, please check: http://south.aeracode.org/ticket/1243 and http://stackoverflow.com/questions/15041265/south-migrate-error-name-uuid-is-not-defined . – pavel_form Jul 23 '14 at 08:56
  • @DanielRoseman built in db migration module doesn't support lambdas. Therefore I can't make automatic migrations. – wswld Jul 23 '14 at 09:01

1 Answers1

0

The comment by @pavel_form helped me to understand the root of my problem. Passing over the callable seems to have fixed that:

class UUIDField(CharField):

    def _gen_uuid(self):
      return uuid.uuid1().bytes.encode('base64').rstrip('=\n').replace('/', '_')

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = kwargs.get('max_length', 22 )
        # kwargs['blank'] = True
        kwargs['default'] = self._gen_uuid
        CharField.__init__(self, *args, **kwargs)

It still causes fair share of problems with the migrations, though. South migrate error: name 'UUID' is not defined (suggested by @pavel-form) takes it even further, omitting definition of the special UUIDFIeld and it is believed to be working well with migrations. I'd be looking in that direction.

Community
  • 1
  • 1
wswld
  • 1,218
  • 15
  • 32