使用 UUID 时 django-taggit 不工作
django-taggit not working when using UUID
我已经阅读了此处的自定义文档 https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#genericuuidtaggeditembase
我正在使用以下代码,当我通过 django admin 保存产品时,tables 被正确填充但是当我阅读产品时,标签会以 None[= 的形式出现14=]
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
上面的代码在我的名为 'catalog' 的 django 应用程序中创建了一个新的 table 'catalog_taggeditem'。还有来自 django-taggit 的默认 table 称为 'taggit_taggeditem'。好像在阅读时,它无法连接点。我不确定,我错过了什么,没有错误。
感谢您的帮助。
--------------------更新--------------------
Product.objects.first().tags.first()
Traceback (most recent call last):
File "/home/chirdeep/envs/order-quick/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: operator does not exist: character varying = uuid
LINE 1: ... = 'product' AND "catalog_taggeditem"."object_id" = '903cda0...
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
我无法重现您的问题。请参阅我在这里使用的来源: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>]>
我在使用 GFK 时遇到了类似的问题。添加显式类型转换对我的情况有所帮助。我不是 100% 确定它会起作用,但请尝试在控制台中执行此操作:
psql -d <your_database>
create cast (uuid as varchar) with inout as implicit;
\q
如果有帮助,您也应该对数据库 template1
做同样的事情(它用作创建新数据库的模板——它会为您为 Django 的单元测试创建的数据库提供正确的设置)。
您收到的错误来自 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 有一个 Django 长期以来支持的本地 UUID 数据类型,所以我不知道这是怎么发生的。也许是不完整的迁移?
在任何情况下,您都可以使用 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);''',
)
我已经阅读了此处的自定义文档 https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#genericuuidtaggeditembase
我正在使用以下代码,当我通过 django admin 保存产品时,tables 被正确填充但是当我阅读产品时,标签会以 None[= 的形式出现14=]
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
上面的代码在我的名为 'catalog' 的 django 应用程序中创建了一个新的 table 'catalog_taggeditem'。还有来自 django-taggit 的默认 table 称为 'taggit_taggeditem'。好像在阅读时,它无法连接点。我不确定,我错过了什么,没有错误。
感谢您的帮助。
--------------------更新--------------------
Product.objects.first().tags.first()
Traceback (most recent call last):
File "/home/chirdeep/envs/order-quick/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: operator does not exist: character varying = uuid
LINE 1: ... = 'product' AND "catalog_taggeditem"."object_id" = '903cda0...
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
我无法重现您的问题。请参阅我在这里使用的来源: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>]>
我在使用 GFK 时遇到了类似的问题。添加显式类型转换对我的情况有所帮助。我不是 100% 确定它会起作用,但请尝试在控制台中执行此操作:
psql -d <your_database>
create cast (uuid as varchar) with inout as implicit;
\q
如果有帮助,您也应该对数据库 template1
做同样的事情(它用作创建新数据库的模板——它会为您为 Django 的单元测试创建的数据库提供正确的设置)。
您收到的错误来自 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 有一个 Django 长期以来支持的本地 UUID 数据类型,所以我不知道这是怎么发生的。也许是不完整的迁移?
在任何情况下,您都可以使用 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);''',
)