django-taggit не работает при использовании UUID - PullRequest
6 голосов
/ 27 мая 2019

Я ознакомился с документацией по настройке здесь https://django -taggit.readthedocs.io / en / latest / custom_tagging.html # genericuuidtaggeditembase

Я использую следующий код, когда я сохраняю продукт через администратор django, таблицы заполняются должным образом, но когда я читаю продукт, теги появляются как None

каталог / 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)

общее / 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_taggeditem' в моем приложении django под названием 'catalog'. Существует также таблица по умолчанию из django-taggit, которая называется taggit_taggeditem. Похоже, что во время чтения, он не может соединить точки. Я не уверен, что мне не хватает, ошибок нет.

Спасибо за вашу помощь.

----------------------- 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.

Ответы [ 3 ]

2 голосов
/ 02 июня 2019

У меня были похожие проблемы при использовании ГФК.Добавление явного приведения типов помогло в моем случае.Я не уверен на 100%, что это будет работать, но попробуйте сделать это в консоли:

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

Если это поможет, вы должны сделать то же самое для базы данных template1 (которая используется в качестве шаблона).для создания новых баз данных - это даст вам правильную настройку для баз данных, созданных для юнит-тестов Django).

0 голосов
/ 03 июня 2019

Ошибка, которую вы получаете, связана с адаптером 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;

Для этого вы можете использовать специальную RunSQL операцию миграции Django.

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);''',
)
0 голосов
/ 02 июня 2019

Я не могу воспроизвести вашу проблему. Смотрите источник, который я использую здесь: 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>]>
...