Issue Adding Multiple TaggableManagers to a Model (or) through parameter does not respect related_name #50

Closed
issackelly opened this Issue Oct 29, 2010 · 13 comments

Projects

None yet
@issackelly

I can't get a custom through field to validate with multiple TaggableManagers on a Model

# -- models.py
from django.db import models
from taggit.managers import TaggableManager
from taggit.models import Tag

class TaggedSkills(models.Model):
   a = models.ForeignKey("ModelA")
   tag = models.ForeignKey(Tag, related_name="%(class)s_skills")

class TaggedInterests(models.Model):
   a = models.ForeignKey("ModelA")
   tag = models.ForeignKey(Tag, related_name="%(class)s_interests")

class TaggedLimitations(models.Model):
   a = models.ForeignKey("ModelA")
   tag = models.ForeignKey(Tag, related_name="%(class)s_limitations")

class ModelA(models.Model):

   skills = TaggableManager(through=TaggedSkills)
   interests = TaggableManager(through=TaggedInterests)
   limitations = TaggableManager(through=TaggedLimitations)

Running

$ manage.py validate
Error: One or more models did not validate:
a.modela: Accessor for m2m field 'skills' clashes with related m2m field 'Tag.modela_set'. Add a related_name argument to the definition for 'skills'.
a.modela: Accessor for m2m field 'skills' clashes with related m2m field 'Tag.modela_set'. Add a related_name argument to the definition for 'skills'.
a.modela: Accessor for m2m field 'interests' clashes with related m2m field 'Tag.modela_set'. Add a related_name argument to the definition for 'interests'.
a.modela: Accessor for m2m field 'interests' clashes with related m2m field 'Tag.modela_set'. Add a related_name argument to the definition for 'interests'.
a.modela: Accessor for m2m field 'limitations' clashes with related m2m field 'Tag.modela_set'. Add a related_name argument to the definition for 'limitations'.
a.modela: Accessor for m2m field 'limitations' clashes with related m2m field 'Tag.modela_set'. Add a related_name argument to the definition for 'limitations'.
@ryankask

I am having a related issue. I would like to be able to tag 'Tag' objects.

Basically certain objects, say Events, are tagged. For example:

"Event: 'Sunday brunch on the beach'" is tagged with 'food, beach'.

I want to be able to Tag the beach tag with 'water-related' so tags can be grouped.

I've tried to put in my settings.py:

from taggit.models import Tag
from taggit.managers import TaggableManager
taggable_manager = TaggableManager()
taggable_manager.contribute_to_class(Tag, 'tags')

But I get the error:
taggit.tag: Reverse query name for m2m field 'tagged_items' clashes with field 'TaggedItem.tag'. Add a related_name argument to the definition for 'tagged_items'.

The code works in the shell when I do it dynamically and I am able to tag Tags, but when I throw it in my settings.py and try to start the shell, it throws that validation error.

It's not the same problem as above but I can't get my head around the issue.

@braskin
braskin commented May 18, 2011

Um.. Has anyone found a fix for the issue Issac opened? I think I am having the same issue..

@tehfink
tehfink commented May 21, 2011

@braskin: hmm, me too…

@jledbetter

Having the same issue as Issac. My user will have 3 tags: interests, skills, and want to learn. But getting the same error when trying to do the same fix. I saw the closed issue that this works as intended but hoping that maybe that changed :)

@selfsimilar

Same issue as Issac. Attempting to add multiple TaggitManager fields to a model (subject, locale, other). Initially getting:

django.core.management.base.CommandError: One or more models did not validate:
labjournal.labjournal: Accessor for m2m field 'locale_tags' clashes with related m2m field 'Tag.labjournal_set'. Add a related_name argument to the definition for 'locale_tags'.
labjournal.labjournal: Accessor for m2m field 'tags' clashes with related m2m field 'Tag.labjournal_set'. Add a related_name argument to the definition for 'tags'.
labjournal.labjournal: Accessor for m2m field 'subject_tags' clashes with related m2m field 'Tag.labjournal_set'. Add a related_name argument to the definition for 'subject_tags'.
labjournal.labjournal: Accessor for m2m field 'tagged_items' clashes with related m2m field 'TaggedItem.labjournal_set'. Add a related_name argument to the definition for 'tagged_items'.
labjournal.labjournal: Accessor for m2m field 'tagged_items' clashes with related m2m field 'TaggedItem.labjournal_set'. Add a related_name argument to the definition for 'tagged_items'.
labjournal.labjournal: Accessor for m2m field 'tagged_items' clashes with related m2m field 'TaggedItem.labjournal_set'. Add a related_name argument to the definition for 'tagged_items'.

by switching to a through relation, I got rid of the 'tagged_items' errors, but I can't get rid of the first three issues even after adding a related_name to the TaggedItemBase subclasses I've created as through relations.

@jledbetter

Went with a through relation and did a bunch of hacking but it's running in Lernanta. Feel free to read through the code to see if it'd help you. Basically had to override some methods.

https://github.com/jledbetter/lernanta/tree/usertagsnew

@philgyford

I'm having what I think is a similar problem: I have two models, from different apps, with the same name. I want to add a TaggableManager to both of them, but I get the same errors because the models have identical names. I think this would be fixed if I could specify a related_name for the TaggableManager...?

What I've done for the moment -- and I'm not sure how horrific this is, but it seems to work -- is to subclass TaggableRel and TaggableManager and provide a related_name:

from django.db import models
from taggit.managers import TaggableManager, TaggableRel

class MyTaggableRel(TaggableRel):
    def __init__(self, *args, **kwargs):
        super(MyTaggableRel, self).__init__(*args, **kwargs)
        self.related_name = "%(app_label)s_%(class)s_related"

class MyTaggableManager(TaggableManager):
    def __init__(self, *args, **kwargs):
        super(MyTaggableManager, self).__init__(*args, **kwargs)
        self.rel = MyTaggableRel()

class Photo(models.Model):
    ...
    # Instead of using the standard TaggableManager.
    tags = MyTaggableManager(blank=True) 
    ...
@sbancal
sbancal commented Oct 19, 2011

Having the same issue... Any official fix?
Thanks

@coderholic

Digging through the code I managed to find out how to do this. The trick is to set the TaggableManager.rel.related_name, eg:

class TaggedSkills(TaggedItemBase):
    content_object = models.ForeignKey("ModelA")

class TaggedInterests(TaggedItemBase):
    content_object = models.ForeignKey("ModelA")

class TaggedLimitations(TaggedItemBase):
     content_object = models.ForeignKey("ModelA")

class ModelA(models.Model):
    skills = TaggableManager(through=TaggedSkills)
    skills.rel.related_name = "+"

    interests = TaggableManager(through=TaggedInterests)
    interests.rel.related_name = "+"

    limitations = TaggableManager(through=TaggedLimitations)
    limitations.rel.related_name = "+"
@gustavodiazjaimes

This is not presciently a solution to the probleme, but I prefere to add an attribute "kind" to tag relation and use proxy models.
https://gist.github.com/2621142

@danfairs

It looks like there's a fix for this here: luminousflux/django-taggit@c687e10

@apollo13
Contributor
apollo13 commented Nov 2, 2013

This is partially fixed in 4595216 -- it's not really nice but should work for now.

@apollo13 apollo13 closed this Nov 2, 2013
@aaugustin

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment