I want to set null and blank to true on all the fields inherited from an abstract model.
My current attempt follows similar SO questions, e.g. overriding the 'default' attribute on ABC and overriding parent model's attribute, which say it is possible. I get the required runtime behaviour, when initialising objects from the python console, but it is not reflected in the migrations file or database.
Context:
I have a System model where I want to be able to create client specific overrides on certain data. I have the following models:
- abstract BaseSystem - defining the overridable fields
- concrete SystemOverride - containing the partially overridden records
- concrete System - containing the 'full' System records.
It is important to make all the fields in SystemOverride null/blank = True so that only the fields that are initialised (by the client) will override the related System object.
Code:
class BaseSystem(models.Model):
class Meta:
abstract = True
def __init__(self, *args, **kwargs):
super(BaseSystem, self).__init__(args, kwargs)
# Mark all fields with 'override' attribute
for field in self._meta.get_fields():
field.override = True
name = models.CharField(max_length=128)
class System(BaseSystem):
pass
class SystemOverride(BaseSystem):
def __init__(self, *args, **kwargs):
super(SystemOverride, self).__init__(args, kwargs)
# Set all overridable fields to null/blank = True.
for field in self._meta.get_fields():
if(hasattr(field, 'override') and field.override):
field.null = True
field.blank = True
# Override-specific fields
system = models.ForeignKey(System)
The result of makemigrations:
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='System',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='SystemOverride',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128)),
('system', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='overide.System')),
],
options={
'abstract': False,
},
),
]
null=True and blank=True have not been added to the name field in SystemOveride.