django-taggit
django-taggit copied to clipboard
tag_model uninitialized in migrations
I'm trying to migrate django-tagging to django-taggit. After having run a migration to add it side-by-side such that it looks like this:
class Flow(models.Model):
tags = TagField()
new_tags = TaggableManager()
I was trying to copy over the tags:
def transfer_tags(apps, schema_editor):
Flow = apps.get_model("flow", "Flow")
for f in Flow.objects.all():
if f.tags:
f.new_tags.add(*f.tags.split(" "))
f.save()
class Migration(migrations.Migration):
dependencies = [
('flow', '0003_flow_new_tags'),
]
operations = [
migrations.RunPython(transfer_tags),
]
But this ran into an AttributeError when running 'migrate':
> ~/env/local/lib/python2.7/site-packages/taggit/managers.py(192)_to_tag_model_instances()
190 for t in tags:
191 import ipdb;ipdb.set_trace()
--> 192 if isinstance(t, self.through.tag_model()):
193 tag_objs.add(t)
194 elif isinstance(t, six.string_types):
ipdb> self.through
<class 'TaggedItem'>
And when I continue, I am getting this error:
AttributeError: type object 'TaggedItem' has no attribute 'tag_model'
I'm facing the same issue
This happens because django creates a state for the migrations. In doing this it does not make models methods accessible - in this case tag_model
.
I'm not sure on a straightforward solution. Any suggestions?
I'm also facing the same issue, when attempting a data migration, but for the "tags_for" attribute.
At migration you need do something like this.
mgr = CustomTaggableManager(through=CustomTaggedItem, model=apps.get_model('my_app', 'MyModelInThisApp'), instance=instance_of_MyModelInThisApp, prefetch_cache_name='tags')
mgr.add('custom_name')
I'm having the same issue.
Would be great to find a solution for this and document it somewhere.
I added this snipped to my data migration and it seemed to work well. Might be nice to generalize it and add a helper utility somewhere.
tags = ['tag1', 'tag2']
Tag = apps.get_model('taggit', 'Tag')
TaggedItem = apps.get_model('taggit', 'TaggedItem')
ContentType = apps.get_model('contenttypes', 'ContentType')
ct = ContentType.objects.get(app_label="myapp", model="mymodel")
for tg in tags:
t, created = Tag.objects.get_or_create(name=tg)
tagged_items, created = TaggedItem.objects.get_or_create(
content_type_id=ct.id,
object_id=my_model_instance.id,
tag=t
)
yeah in a data migration you'll have to do stuff by hand (copying to through tables etc). If anyone could write up a small guide for steps going from django-tagging
to django-taggit
we can put it in the docs
I added this snipped to my data migration and it seemed to work well. Might be nice to generalize it and add a helper utility somewhere.
tags = ['tag1', 'tag2'] Tag = apps.get_model('taggit', 'Tag') TaggedItem = apps.get_model('taggit', 'TaggedItem') ContentType = apps.get_model('contenttypes', 'ContentType') ct = ContentType.objects.get(app_label="myapp", model="mymodel") for tg in tags: t, created = Tag.objects.get_or_create(name=tg) tagged_items, created = TaggedItem.objects.get_or_create( content_type_id=ct.id, object_id=my_model_instance.id, tag=t )
@steverecio
What do you do with the tagged_items
after this though? I'm trying to get this to work with a data migration as well, and trying to save the TaggedItem back to mymodel
is not working, and still giving me the same error.