Skip to content

Instantly share code, notes, and snippets.

@kkubasik
Created June 3, 2010 14:38
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 kkubasik/0212845ae00891efe555 to your computer and use it in GitHub Desktop.
Save kkubasik/0212845ae00891efe555 to your computer and use it in GitHub Desktop.
def create_preview_model(cls):
"Create a preview model for a PreviewModel"
name = cls.__name__ + "Preview"
#Set up a dictionary to simulate declarations within a class
attrs = {
'__module__': cls.__module__,
}
#OneToOne to the model we are previewing
attrs['preview_parent'] = models.OneToOneField(cls, related_name='preview')
attrs['__str__'] = preview_string
#duplicate all fields into this class, set your dependencies if any
cls.dependencies = []
for field in cls._meta.fields:
if field.name != "preview_state":
if isinstance(field, (ForeignKey, OneToOneField, ManyToManyField)):
field_class = type(field)
rel = field.rel
field_dict = { "unique": field.unique,
"null": field.null,
"blank": field.blank
}
if rel.related_name:
field_dict["related_name"] = "preview" + rel.related_name
attrs[field.name] = field_class(rel.to, **field_dict)
#if the dependency is a PreviewModel we will notify it of the model's current status
dependency_fields = [f.name for f in rel.to._meta.fields]
is_required = not field.blank and (not field.null or isinstance(field, ManyToManyField))
if "preview_state" in dependency_fields and is_required:
cls.dependencies.append(field.name)
else:
attrs[field.name] = field
#create the new class and set it on the PreviewModel class for later access
new_class = type(name, (models.Model,), attrs)
cls.preview_class = new_class
return new_class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment