django-taggit在使用UUID时不起作用

时间:2019-05-26 22:28:03

标签: python django django-taggit

我在https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#genericuuidtaggeditembase

处浏览了自定义文档

我正在使用以下代码,当我通过django admin保存产品时,表已正确填充,但是当我读取产品时,标签将显示为None

catalog / models.py

from django.db import models
from django.db.models import ImageField
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _

from taggit.managers import TaggableManager
from taggit.models import GenericUUIDTaggedItemBase, TaggedItemBase

from common.models import ModelBase
from customer.models import ApplicationUser
from order_quick.settings import APPLICATION_CURRENCY_SYMBOL


class TaggedItem(GenericUUIDTaggedItemBase, TaggedItemBase):
    class Meta:
        verbose_name = _("Tag")
        verbose_name_plural = _("Tags")


class Product(ModelBase):
    supplier = models.ForeignKey(ApplicationUser, on_delete=models.DO_NOTHING)
    name = models.CharField(max_length=255)
    description = models.CharField(max_length=255)
    image = ImageField(upload_to='images/products/', blank=True, null=True)
    cost_price = models.DecimalField(max_digits=9,
                                     decimal_places=2,
                                     verbose_name="Cost Price " + "(" + APPLICATION_CURRENCY_SYMBOL + ")")
    selling_price = models.DecimalField(max_digits=9,
                                        decimal_places=2,
                                        verbose_name="Selling Price " + "(" + APPLICATION_CURRENCY_SYMBOL + ")")
    is_active = models.BooleanField(default=True)
    tags = TaggableManager(through=TaggedItem)

    def __str__(self):
        return "{0}".format(self.name)

common / models.py

import uuid
from enum import Enum

from django.db import models


class ModelBase(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

上面的代码在我的Django应用程序“ catalog”中创建了一个新表“ catalog_taggeditem”。 django-taggit中还有一个默认表,称为“ taggit_taggeditem”。好像在阅读时,它无法连接各个点。我不确定,我缺少什么,没有错误。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

使用GFK时,我遇到类似的问题。在我的情况下,添加显式类型强制转换很有帮助。我不是100%确信它会起作用,但是请尝试在控制台中执行此操作:

psql -d <your_database>
create cast (uuid as varchar) with inout as implicit;
\q

如果有帮助,您还应该对数据库template1(用作创建新数据库的模板-它将为您为Django的单元测试创​​建的数据库进行正确的设置)做同样的事情。

答案 1 :(得分:0)

我无法重现您的问题。在此处查看我使用的来源:https://github.com/jayhale/so-django-taggit

标记已成功创建并且可以检索:

$ python manage.py shell
Python 3.7.2 (default, Dec 27 2018, 07:35:06) 
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from taggit_app.models import Product
>>> p = Product()
>>> p.save()
>>> p
<Product: Product object (71a56d92-13eb-4d7d-9e67-46c9cd1daa19)>
>>> p.tags.add('a', 'b', 'c')
>>> p.tags.all()
<QuerySet [<Tag: c>, <Tag: b>, <Tag: a>]>

答案 2 :(得分:0)

您遇到的错误来自postgres适配器。由于某种原因,object_id列的类型似乎为varying(varchar),而不是预期的uuid

psycopg2.ProgrammingError: operator does not exist: character varying = uuid
LINE 1: ... = 'product' AND "catalog_taggeditem"."object_id" = '903cda0...

Postgres具有本地的UUID数据类型,Django长期以来一直支持该数据类型,所以我不知道这怎么可能发生。也许迁移不完整?

在任何情况下,都可以使用SQL将整个数据库列转换为新类型。假设问题仅出在此特定错误中提到的列,则可以执行类似的操作。

ALTER TABLE catalog_taggeditem ALTER COLUMN object_id TYPE uuid USING object_id::uuid;

您可以为此使用Django的特殊RunSQL迁移操作。

migrations.RunSQL(
    sql='''
        ALTER TABLE catalog_taggeditem 
        ALTER COLUMN object_id TYPE uuid 
        USING object_id::uuid;''',
    reverse_sql='''
        ALTER TABLE catalog_taggeditem 
        ALTER COLUMN object_id TYPE varchar(32) 
        USING object_id::varchar(32);''',
)