django-taggit在UUID作为pk的模型上抛出超出范围的保存

时间:2015-07-28 17:24:50

标签: django django-taggit django-contenttypes

我有使用UUID作为PK的模型

class Foo(models.Model):        
    foo_id = models.UUIDField(  
        primary_key=True,             
        default=uuid.uuid4,           
        editable=False                
    )  
    tags = TaggableManager()        

当我去尝试添加新标签时

f = Foo.objects.latest('pk')
f.tags.add("testing")

我得到DataError: integer out of range

当我在光标上导入pdb以查看进入的SQL时,我看到了这一点。

(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"'    

试图插入的长整数(287082253891563438098836942573405313042)显然是导致错误的原因。此数字是UUID

foo_id的整数
In [6]: foo.foo_id.int                      
Out[6]: 287082253891563438098836942573405313042  

我可以设置一些内容以允许django-taggitcontenttypesUUID很好地配合吗?

2 个答案:

答案 0 :(得分:2)

这是基于奥斯汀评论的答案。

django-taggit中,对标记模型的引用存储在名为GenericTaggedItemBase的名为object_id的模型中。 object_id字段已硬编码为models.IntegerField。因此,无法标记具有UUID主键的模型。代码为located here

如果您需要标记的所有模型属于同一类型(在本例中为models.UUIDField),那么您可以将object_id的类型设置为models.UUIDField

以下是必须进行的更改,假设您正在使用virtualenvwrapper

  1. 在站点包文件夹中找到taggit包。 ~/virtualenvs/<your_virtualenv>/lib/<python_version>/site-packages/taggit

  2. taggit目录复制到项目中。

  3. taggit

  4. 删除site-packages目录
  5. models.py的{​​{1}}文件中,替换

  6. taggit

    object_id = models.IntegerField(verbose_name=_('Object id'), db_index=True)
    1. 迁移taggit。
    2. object_id = models.UUIDField(verbose_name=_('Object id'), db_index=True)

      python manage.py makemigrations taggit

答案 1 :(得分:2)

由于我缺乏声誉点,我无法评论,

我希望扩展@Pramod响应,这对我找到正确的答案非常有帮助:

Taggit 有另一个类,可以更改TaggedItem的行为

这里有一个如何实现这个目标的片段:

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)

来源:http://django-taggit.readthedocs.io/en/latest/custom_tagging.html#genericuuidtaggeditembase