The following model setup:
class City(models.Model): name = models.CharField(max_length=50) class Meta: app_label = 'locations' class Street(models.Model): name = models.CharField(max_length=50) city = models.ForeignKey(City) class Meta: app_label = 'locations'
Can be reproduced doing the following:
# Create the table and the model city_model_def = ModelDefinition.objects.create( app_label='locations', object_name='City' ) # Add a column to the table and update the model CharFieldDefinition.objects.create( model_def=city_model_def, name='name', max_length=50 ) # Create the second table and model street_model_def = ModelDefinition.objects.create( app_label='locations', object_name='Street' ) # Add the columns CharFieldDefinition.objects.create( model_def=street_model_def, name='name', max_length=50 ) ForeignKeyDefinition.objects.create( model_def=street_model_def, name='city', to=city_model_def ) # Now you can retreive model class from definitions City = city_model_def.model_class() Street = street_model_def.model_class() montreal = City.objects.create(name='Montréal') papineau = Street.objects.create(city=montreal, name='Papineau')
Adding fields after model creation issues extra ALTER
statements.
For example the following code:
model_def = ModelDefinition.objects.create( app_label='app', object_name='Model' ) CharFieldDefinition.objects.create( model_def=model_def, name='field', max_length=50 )
Would issue the following SQL:
CREATE TABLE app_model { ... }; ALTER TABLE app_model ADD COLUMN name ...;
To include the field
in table creation you can use the fields
kwarg of the create
or get_or_create
method of the ModelDefinitionManager
:
field = CharFieldDefinition(name='field', max_length=50) ModelDefinition.objects.create( app_label='app', object_name='Model', fields=[field] )
Mutant comes bundled with FieldDefinition
associated with all
the database fields that comes with Django.
For example, the django.contrib.gis
field definitions can be found
in the mutant.contrib.geo
app:
from mutant.contrib.geo.models import GeoModel, PointFieldDefinition from mutant.models import BaseDefinition, ModelDefinition ModelDefinition.objects.create( app_label='myapp', object_name='MyModel', bases=[BaseDefinition(base=GeoModel)], fields=[PointFieldDefinition(name='point')] )
Note that here we use GeoModel
as an abstract base to inherit
its GeoManager
.