1
votes

How to use the IN operator with uuid - Django?

Model

class Client(models.Model):

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    nome    = models.CharField(max_length=255)
    email    = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.nome

class Subscription(models.Model):

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    vencimento = models.DateField()
    client = models.OneToOneField(Client, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

View

 clients = Client.objects.filter(nome__icontains=q).values_list('pk', flat=True)
 subscriptions = Subscription.objects.filter(client_id__in=clients)

I tried using this to convert and it still does not work.

clients = [str(o) for o in clients]

Where am I going wrong?

Thank you.

I also tried this

subscriptions = Subscription.objects.filter(client__nome__icontains=q)

Query

SELECT "app_subscription"."id", "app_subscription"."vencimento","app_subscription"."client_id", "app_subscription"."created_at", "app_subscription"."updated_at" FROM "app_subscription" INNER JOIN "cad_client" ON ("app_subscription"."client_id" = "cad_client"."id") WHERE "cad_client"."nome" LIKE %marcelo% ESCAPE '\' 

ERROR

psycopg2.ProgrammingError: operator does not exist: character varying = uuid

operator does not exist: character varying = uuid LINE 1: ...client" ON ("app_subscriptions"."client_id" = "clien... ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.

4
Share any errors if any.Atley Varghese

4 Answers

0
votes

Try to convert it to list:

clients_list = list(Client.objects.filter(nome__icontains=q).values_list('pk', flat=True))
subscriptions = subscription.objects.filter(client__id__in=clients_list)
0
votes

First thing, your model does not contain the nome filed. So, assuming it does, your query returns a queryset. So, for the IN to work, what you want to pass in is a list.

clients = Client.objects.filter(nome__icontains=q).values_list('pk', flat=True)
clients = list(clients)
subscriptions = Subscription.objects.filter(client_id__in=clients)
0
votes

There's no reason to use two queries, or even a subquery, here. A simple related lookup is what you need.

subscriptions = Subscription.objects.filter(client__nome__icontains=q)

But note that your actual error, as others have pointed out, is probably because your Client model does not appear to contain a nome field.

0
votes
class Subscription(models.Model):

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    vencimento = models.DateField()
    client = models.OneToOneField(Client, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

This column in the database was not of the uuid type. He was with Varchar.

So it was not possible to compare.

Just change the type of the Varchar column to uuid in the database.

Thank you all for your attention.

client = models.OneToOneField(Client, on_delete=models.CASCADE)