Login

decorator to add GUID Field to Django Models

Author:
trubliphone
Posted:
February 3, 2013
Language:
Python
Version:
1.4
Score:
0 (after 0 ratings)

A decorator to add a GUID Field to a Django Model. There are other bits of code out there that do similar things, but it was important for the field to have a unique value before it is saved in the database. The contribute_to_class method therefore registers the field class with the post_init signal of the class it's being added to. The handler for that signal is where field initialization is done.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 3 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

Please login first before commenting.