djangodjango-southdjango-treebeard

Adding default tags via data migration


I am using hierarchical tags which work with taggit and treebeard. I am trying to get a data migration so I can define so tags that will be present in all instances of the app.

I have this method defined:

def define_tags(apps, schema_editor):
    HierarchicalTag = apps.get_model("aion", "HierarchicalTag")
    root = HierarchicalTag.add_root(name='root')
    root.save()
    leaf = HierarchicalTag.objects.get(pk=root.pk).add_child(name='ook')
    leaf.save()

which should create two tags "root" and a child "ook". However, when I run the migration, I get this error:

AttributeError: type object 'HierarchicalTag' has no attribute 'add_root'

The method add_root is a class method of MP_Node from treebeard.

How can I fix this?


Solution

  • TLDR: you can't use the treebeard API if you use app.get_model rather than importing it.

    When you use

    HierarchicalTag = apps.get_model("aion", "HierarchicalTag")
    

    to get the HeirarchicalTag model rather than importing it, you actually don't get the treebeard API. You're not getting the model as it's defined in your code, you're getting django's inferred version of the model based on your migrations. That's why app.get_model will continue to work after you delete the actual code for a certain model (and that is why you use app.get_model in migrations rather than importing).

    Solutions:

    1. Write a destined-to-eventually-fail migration that just imports HierarchicalTag.
    2. Continue to use app.get_model but then insert roots manually (see the django-treebeard api to figure out which fields need to be filled out manually).