简体   繁体   English

django-taggit在使用UUID时无法正常工作

[英]django-taggit not working when using UUID

I have gone through the customization documentation here https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#genericuuidtaggeditembase 我在这里查看了自定义文档https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#genericuuidtaggeditembase

I am using the following code, when I save the product through django admin, tables are getting populated properly but when I am reading a product, tags are coming as None 我正在使用以下代码,当我通过django admin保存产品时,表格正在填充,但是当我正在阅读产品时,标签将变为无

catalog/models.py 目录/ 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 通用/ 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

The code above create a new table 'catalog_taggeditem' in my django application called 'catalog'. 上面的代码在我的django应用程序中创建了一个名为'catalog'的新表'catalog_taggeditem'。 There is also the default table from django-taggit called 'taggit_taggeditem'. django-taggit还有一个名为'taggit_taggeditem'的默认表。 Seems like while reading, it can't connect the dots. 看起来像在阅读时,它无法连接点。 I am not sure, what am I missing, there are no errors. 我不确定,我错过了什么,没有错误。

Thanks for your help. 谢谢你的帮助。

-----------------------UPDATE-------------------- ----------------------- UPDATE --------------------

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.

I had similar issues, when used GFKs. 当使用GFK时,我遇到了类似的问题。 Adding explicit types cast helped in my case. 在我的例子中添加显式类型转换有帮助。 I'm not 100% sure it will work, but try to do this in console: 我不是100%肯定它会起作用,但尝试在控制台中执行此操作:

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

If it will help, you should also do the same for database template1 (which is used as template for new databases creation — it will give you proper setup for the databases created for Django's unittests). 如果它有用,你也应该对数据库template1 (用作新数据库创建的模板)做同样的事情 - 它将为你为Django的单元测试创​​建的数据库提供正确的设置。

I'm not able to reproduce your issue. 我无法重现您的问题。 See the source I'm using here: https://github.com/jayhale/so-django-taggit 请参阅我在这里使用的来源: https//github.com/jayhale/so-django-taggit

Tags are successfully created and are retrievable: 标签已成功创建并可检索:

$ 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>]>

The error you are getting comes from the postgres adapter. 你得到的错误来自postgres适配器。 For some reason the object_id column seems to be of type varying (varchar) instead of the expected uuid . 出于某种原因,OBJECT_ID列似乎型varying (VARCHAR),而不是预期的uuid

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

Postgres has a native UUID datatype which Django has supported for a long time, so I don't know how this could have happened. Postgres有一个原生的UUID数据类型,Django已经支持了很长时间,所以我不知道这是怎么回事。 Maybe an incomplete migration? 也许是不完整的迁移?

In any case, you can convert an entire database column to a new type with SQL. 在任何情况下,您都可以使用SQL将整个数据库列转换为新类型。 Assuming the problem is only with the column mentioned in this specific error, something like this can work. 假设问题仅出现在此特定错误中提到的列,则可以使用此类操作。

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

You can use Django's special RunSQL migration operation for this. 您可以使用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);''',
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM