1 | class ForeignKey:
|
---|
2 | fkeys_to_name = {} # Keyed by object's id
|
---|
3 | def __init__(self, otherclass):
|
---|
4 | self.otherclass = otherclass
|
---|
5 | self.default_name = self.otherclass.__name__.lower()
|
---|
6 | self.name = None # Will be set later
|
---|
7 |
|
---|
8 | # Keep a reference to this instance around
|
---|
9 | ForeignKey.fkeys_to_name[id(self)] = self
|
---|
10 |
|
---|
11 | class ModelBase(type):
|
---|
12 | # Metaclass for Model objects
|
---|
13 | def __new__(cls, name, bases, attrs):
|
---|
14 | if not bases:
|
---|
15 | return type.__new__(cls, name, bases, attrs)
|
---|
16 | new_class = type.__new__(cls, name, bases, attrs)
|
---|
17 | for name, obj in attrs.items():
|
---|
18 | if isinstance(obj, ForeignKey):
|
---|
19 | obj.name = name
|
---|
20 | del ForeignKey.fkeys_to_name[id(obj)]
|
---|
21 | # Now all named ForeignKeys are gone, only unnamed ones remain
|
---|
22 | for fkey in ForeignKey.fkeys_to_name.values():
|
---|
23 | fkey.name = fkey.default_name
|
---|
24 | setattr(new_class, fkey.name, fkey)
|
---|
25 | ForeignKey.fkeys_to_name = {} # Reset for next class
|
---|
26 | return new_class
|
---|
27 |
|
---|
28 | class Model:
|
---|
29 | __metaclass__ = ModelBase
|
---|
30 |
|
---|
31 | class One(Model):
|
---|
32 | pass
|
---|
33 |
|
---|
34 | class Two(Model):
|
---|
35 | pass
|
---|
36 |
|
---|
37 | class SampleRecord(Model):
|
---|
38 | ForeignKey(One)
|
---|
39 | ForeignKey(Two)
|
---|
40 |
|
---|
41 | if __name__ == '__main__':
|
---|
42 | for name, val in SampleRecord.__dict__.items():
|
---|
43 | print name, '=', val
|
---|
44 | if isinstance(val, ForeignKey):
|
---|
45 | print val, 'knows its name is', val.name
|
---|