Is There A Way In A Seed_data.yaml File To Autogenerate Models On Which First Model Is Dependent Upon?
Solution 1:
Answer : Update your fixtures as per the following
- model: test_app.coop
pk: 1
fields:
name: '1871'
type:
- Coworking Space
enabled: true
email: null
web_site: ''
- model: test_app.coop
pk: 2
fields:
name: '18715'
type:
- Coworking Space 2
enabled: true
email: null
web_site: ''
- model: test_app.coop
pk: 3
fields:
name: '187156'
type:
- Coworking Space 3
enabled: true
email: null
web_site: ''
And add a custom manager in your CoopType
model
class CoopManager(models.Manager):
def get_by_natural_key(self, name):
return self.get_or_create(name=name)[0]
class CoopType(models.Model):
name = models.CharField(max_length=200)
objects = CoopManager()
class Meta:
unique_together = ("name",)
Now when you load the fixtures it will create the CoopType
objects if not already exists and then load Coop
model
Explanation: This is the Django code responsible for deserializing the objects
# Handle FK fields
elif field.remote_field and isinstance(field.remote_field, models.ManyToOneRel):
model = field.remote_field.model
if field_value is not None:
try:
default_manager = model._default_manager
field_name = field.remote_field.field_name
if hasattr(default_manager, 'get_by_natural_key'):
if hasattr(field_value, '__iter__') and not isinstance(field_value, six.text_type):
obj = default_manager.db_manager(db).get_by_natural_key(*field_value)
value = getattr(obj, field.remote_field.field_name)
# If this is a natural foreign key to an object that
# has a FK/O2O as the foreign key, use the FK value
if model._meta.pk.remote_field:
value = value.pk
else:
value = model._meta.get_field(field_name).to_python(field_value)
data[field.attname] = value
else:
data[field.attname] = model._meta.get_field(field_name).to_python(field_value)
except Exception as e:
raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value)
else:
data[field.attname] = None
Source: django.core.serializers.python line 152 onwards
As you can see if get_by_natural_key
function is given in model and fixtures has nested data then it calls get_by_natural_key
function to get the object. So in get_by_natural_key
function we can use get_or_create
and return the instance.
Please check that nested data in the Coop
model has only args
and not the kwargs
because Django code pass args
in this function.
PS: I am not sure how correct it is to use get_or_create
in get_by_natural_key
function but This is the only working solution for now.
Post a Comment for "Is There A Way In A Seed_data.yaml File To Autogenerate Models On Which First Model Is Dependent Upon?"