Login

ImportObject: Import model *instance* specific code at runtime

Author:
guettli
Posted:
August 13, 2009
Language:
Python
Version:
1.1
Score:
1 (after 1 ratings)

See docstring

 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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
class ImportObject(models.Model):
    u'''
    Base class to import model *instance* specific code at runtime.

    By default the model instance contains a python import string (myapp.foo.MyClass)
    in the primary key.

    Example:
        my_workflow=WorkflowDefinition.objects.get(pk='myapp.foo.MyClass')
        my_workflow.object --> instance of myapp.foo.MyClass

    myapp.foo.MyClass can be a normal Python class or a Model subclass.

    If myapp.foo.MyClass is a subclass of Model. It should have a
    OneToOneField to (in this example) WorkflowDefinition.

    Why not use content types and generic relations which are provided
    by django?  The imported class don't need to be a model. It can be
    plain python class.  Next argument: because it does not use serial
    (auto increment) primary keys.  Explicit primary keys don't clash
    if you want to deploy applications in several projects.

    '''
    class Meta:
        abstract=True
    _import_object_attribute='pk'
    _cls=None
    @property
    def cls(self):
        if not self._cls is None:
            return self._cls
        import_string=getattr(self, self._import_object_attribute)
        if not import_string:
            cls=None
        else:
            if isinstance(import_string, models.Model):
                import_string=import_string.pk # myapp.foo.MyClass
            cls=import_from_string(import_string)
        
        self._cls=cls
        return cls

    _object=None
    @property
    def object(self):
        if not self._object is None:
            return self._object
        cls=self.cls
        if cls is None:
            obj=None
        else:
            if issubclass(cls, models.Model):
                obj=self.cls.objects.get(pk=self)
            else:
                obj=self.cls(self)

        self._object=obj
        return obj

def import_from_string(to_import):
    u'''
    Import a object (variable, method, class ...) with a string.
    Example: 'myapp.models.FooModel'
    '''
    if not '.' in to_import:
        raise ImportError('No "." in %r' % to_import)
    idx=to_import.rindex('.')
    module_name=to_import[:idx]
    attr=to_import[idx+1:]
    module=__import__(module_name, {}, {}, [attr])
    something=getattr(module, attr, None)
    if not something:
        raise ImportError('module %s has no attribute %r' % (module_name, attr))
    return something
                                                              

More like this

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

Comments

Please login first before commenting.