Skip to content

Instantly share code, notes, and snippets.

@tbarbugli
Created April 2, 2012 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tbarbugli/2283830 to your computer and use it in GitHub Desktop.
Save tbarbugli/2283830 to your computer and use it in GitHub Desktop.
OneToOneModelFactory
from django.db import models
from django.utils.importlib import import_module
class OneToOneModelFactory(object):
"""
creates related models :cls
which are subclasses of :subclass named :subclasses
convenient to define a bunch of related models programmatically
(eg. localize table columns in separate tables)
class Animal(models.Model):
...
class Flying(models.Model):
wings = models.IntegerField()
class Meta:
abstract = True
ModelSubClassFactory(Animal, Flying, ['Bat', 'Cow'])
registers AnimalBat and AnimalCow models
"""
def __init__(self, cls, subclass, subclasses):
self.create_subclasses(cls, subclass, subclasses)
def create_subclasses(self, cls, subclass, subclasses):
mod = import_module(cls.__dict__['__module__'], __name__)
attrs = self.get_subclass_attrs(cls)
if isinstance(subclass, (list, tuple)):
subclass_tuple = tuple(subclass)
else:
subclass_tuple = (subclass, )
for sub_cls in subclasses:
sub_cls_name = self.get_subclass_name(cls, sub_cls)
model_cls = type(sub_cls_name, subclass_tuple, attrs.copy())
setattr(mod, sub_cls_name, model_cls)
def get_subclass_attrs(self, base_class):
attrs = {
base_class.__name__.lower(): models.OneToOneField(base_class),
'__module__': base_class.__dict__['__module__']
}
return attrs
def get_subclass_name(self, cls, subclass):
return "%s%s" % (cls.__name__, subclass.capitalize())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment