Skip to content
This repository

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

Closed
issackelly opened this Issue · 13 comments

13 participants

Issac Kelly Ryan Kaskel Boris Raskin tehfink Jessica Ledbetter Colin Sheaff Phil Gyford Samuel Bancal Ben Dowling Gustavo Díaz Jaimes Dan Fairs Florian Apolloner Aymeric Augustin
Issac Kelly

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'.
Ryan Kaskel

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.

Boris Raskin
braskin commented

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

tehfink
tehfink commented

@braskin: hmm, me too…

Jessica Ledbetter

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 :)

Colin Sheaff

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.

Jessica Ledbetter

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

Phil Gyford

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) 
    ...
Samuel Bancal

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

Ben Dowling

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 = "+"
Gustavo Díaz Jaimes

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

Dan Fairs

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

Florian Apolloner
Collaborator

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

Aymeric Augustin

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.