Jagulari
Jagulari

Reputation: 81

django query returns error: expected str instance, ValuesListQuerySet found

I have a script, which takes the values from the list_of_animals one by one and performs some actions with them.
It works like this:

list_of_animals = ["Dog", "Cat", "Fish"]
for x in list_of_animals:
...

The code loops over this list, one animal at a time and finishes.

Now, for the next step, I have a model like this:

class MyModel(models.Model):
animal = models.CharField(max_length=25, unique=True, error_messages=
{'unique':"This animal is added already."})
timestamp = models.DateTimeField()

...and a lot more animals in the SQLite database. So I try to replace that manually created list_of_animals with a query.

I tried to change the list_of_animals like this:

list_of_animals = [MyModel.objects.values_list('title', flat=True)]

But I'm getting error :

expected str instance, ValuesListQuerySet found

Actually I tried many other ways also, but without success.
Can you help me to find a way to replace manually created list with a query that works the same way?

Thank you!

Upvotes: 1

Views: 301

Answers (2)

Anshul Goyal
Anshul Goyal

Reputation: 76887

Instead of doing list_of_animals = [MyModel.objects.values_list('title', flat=True)], do

list_of_animals = MyModel.objects.values_list('title', flat=True)

the MyModel will return an iterable list by default if you use flat=True with single fields list, as mentioned in documentation here:

If you only pass in a single field, you can also pass in the flat parameter. If True, this will mean the returned results are single values, rather than one-tuples. An example should make the difference clearer:

>>> Entry.objects.values_list('id').order_by('id')
[(1,), (2,), (3,), ...]

>>> Entry.objects.values_list('id', flat=True).order_by('id')
[1, 2, 3, ...]

Upvotes: 2

André Laszlo
André Laszlo

Reputation: 15537

Try:

list_of_animals = list(MyModel.objects.values_list('title', flat=True))

From the docs:

Note that this method returns a ValuesListQuerySet. This class behaves like a list. Most of the time this is enough, but if you require an actual Python list object, you can simply call list() on it, which will evaluate the queryset.

Upvotes: 2

Related Questions