I have models that uses UUID as its PK
class Foo(models.Model):
foo_id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False
)
tags = TaggableManager()
When I go and try to add a new tag
f = Foo.objects.latest('pk')
f.tags.add("testing")
I get DataError: integer out of range
When I import pdb on the cursor to view the SQL going in I see this.
(Pdb) params
(1, 287082253891563438098836942573405313042, 9)
(Pdb) sql
'INSERT INTO "taggit_taggeditem" ("tag_id", "object_id", "content_type_id") VALUES (%s, %s, %s) RETURNING "taggit_taggedit
m"."id"'
That long integer (287082253891563438098836942573405313042
) trying to be insterted is obvsiouly the cause for the error. This number is the int of the UUID
for foo_id
In [6]: foo.foo_id.int
Out[6]: 287082253891563438098836942573405313042
Is there something I can set to allow django-taggit
to play nicely with contenttypes
and UUID
?
I'd like to extend @Pramod response, that was very helpful for me to find the right answer:
Taggit has another class that allows to change the behavior of the TaggedItem
Here is a snippet of how to implement this solution:
from django.db import models
from django.utils.translation import ugettext_lazy as _
from taggit.managers import TaggableManager
from taggit.models import GenericUUIDTaggedItemBase, TaggedItemBase
class UUIDTaggedItem(GenericUUIDTaggedItemBase, TaggedItemBase):
# If you only inherit GenericUUIDTaggedItemBase, you need to define
# a tag field. e.g.
# tag = models.ForeignKey(Tag, related_name="uuid_tagged_items", on_delete=models.CASCADE)
class Meta:
verbose_name = _("Tag")
verbose_name_plural = _("Tags")
class Food(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
# ... fields here
tags = TaggableManager(through=UUIDTaggedItem)
source: http://django-taggit.readthedocs.io/en/latest/custom_tagging.html#genericuuidtaggeditembase
Here's an answer based on Austin's comment.
In django-taggit
, references to tagged models are stored in a model named GenericTaggedItemBase
under a field called object_id
. The object_id
field is hardcoded to models.IntegerField
. So it's not possible to tag models having UUID primary keys. The code is located here.
If all your models that need to be tagged are of the same type (in this case, models.UUIDField
), then you can set object_id
's type to models.UUIDField
.
Here are the changes that have to be made, assuming you're using virtualenvwrapper
Locate the taggit
package in the site packages folder. ~/virtualenvs/<your_virtualenv>/lib/<python_version>/site-packages/taggit
Copy the taggit
directory into your project.
Delete the taggit
directory from site-packages
In the models.py
file in taggit
, replace
object_id = models.IntegerField(verbose_name=_('Object id'), db_index=True)
with
object_id = models.UUIDField(verbose_name=_('Object id'), db_index=True)
python manage.py makemigrations taggit
python manage.py migrate
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With