Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

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

The code above create a new table 'catalog_taggeditem' in my django application called 'catalog'. There is also the default table from django-taggit called '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--------------------

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.
like image 775
Chirdeep Tomar Avatar asked May 26 '19 22:05

Chirdeep Tomar


People also ask

What are the options for UUID fields in Django?

Here are the option and attributes that an UUIDField can use. If True, Django will store empty values as NULL in the database. Default is False. If True, the field is allowed to be blank. Default is False. The name of the database column to use for this field. If this isn’t given, Django will use the field’s name.

How to use non-integer primary keys in Django taggit?

A common use case of a non-integer primary key, is UUID primary key. django-taggit provides a base class GenericUUIDTaggedItemBase ready to use with models using an UUID primary key: When providing a custom Tag model it should be a ForeignKey to your tag model named "tag".

How to get a list of tags in Django-taggit?

By default django-taggit uses taggit.utils._parse_tags which accepts a string which may contain one or more tags and returns a list of tag names.

How does Django-taggit handle foreign keys?

By default django-taggit uses a “through model” with a GenericForeignKey on it, that has another ForeignKey to an included Tag model.


1 Answers

I had similar issues, when used GFKs. Adding explicit types cast helped in my case. I'm not 100% sure it will work, but try to do this in console:

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

like image 194
Igor Pomaranskiy Avatar answered Oct 19 '22 04:10

Igor Pomaranskiy