Skip to content Skip to sidebar Skip to footer

Is There A Way In A Seed_data.yaml File To Autogenerate Models On Which First Model Is Dependent Upon?

I'm using Django 2.0, Python 3.7, and MySql 5. I have the following two models, the second dependent on the first ... class CoopType(models.Model): name = models.CharField(max

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?"