from django.db import models
from uuid import uuid4
import types
class GUIDField(models.CharField):
"""
A ModelField to store a GUID
"""
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 64 )
kwargs['unique'] = kwargs.get('unique', True )
kwargs['editable'] = kwargs.get('editable', False )
kwargs['blank'] = kwargs.get('blank', False )
super(GUIDField, self).__init__(*args, **kwargs)
def contribute_to_class(self,cls,name):
"""
called when a GUIDField is added to a class
this inserts the "getGUID" fn to that class
it also registers a callback w/ the cls post_init signal
(so that I can give it a unique value then)
"""
def _getGUID(self):
return self._guid
cls.getGUID = types.MethodType(_getGUID,None,cls)
# connect cls 'post_init' signal to the setValue() method
post_init.connect(self.setValue,cls)
super(GUIDField,self).contribute_to_class(cls,name)
def setValue(self,*args,**kwargs):
"""
actually sets the GUID value
"""
instance = kwargs.get("instance",None)
if instance:
if not instance._guid:
# only set the GUID if it hasn't already been set by __init__
instance._guid = str(uuid4())
def guid():
"""
decorator that specifies that a model has a _guid element,
which can be accessed using the getGUID() method.
"""
def decorator(obj):
# create the field
guid_field = GUIDField(default=str(uuid4()))
# add it to the object
guid_field.contribute_to_class(obj, "_guid")
# return the modified object
return obj
return decorator
Comments