values ()
error in Django ORMDjango ORM has similar methods, <Model> .objects.values ()
and <Model> .objects.only ()
, values ()
and ʻonly ()`, but a little I was addicted to it, so as a memorandum.
The origin of this is that when I wrote a code like ↓, I got the following error.
president1 = Company.objects.values(*fields)[0].president
# =>error: AttributeError: 'dict' object has no attribute 'president'
Here, from the model Company
, using thevalues ()
method of Django ORM,
I'm trying to get the value of the president
field of the first element of a queryset (like a Python list with an iterable data type that contains multiple objects) that was generated by extracting only certain fields ..
However, at runtime I got the error ʻAttribute Error:'dict' object has no attribute'president'`.
Even after reviewing the model definition, I found out that the field president
does exist, but this is strange. difference between values () and only () was helpful.
values ()
returns ValuesQuerySet
instead of QuerySet
According to the reference article, the values ()
method returns an object of the data type ValuesQuerySet
.
Based on QuerySet
, it returns ** an array of elements converted from object fields into a dictionary (= ValuesQuerySet) **.
In other words, in the above code, I was trying to retrieve field data from the dictionary {'president':'xxx', ...}
using .president
, so I got an error.
Since it is a dictionary, using ['president']
means that no error occurred.
When you read the error message, it says 'dict' object
. ..
returns
QuerySet`So, if you want QuerySet
like this case, you can use ʻonly ()` [^ 1]. This time, the element is not a dictionary, but an instance of the class is returned properly, so no error occurs.
By the way, QuerySet
is iterable, but be careful because the data type is different from list
(because it is similar, I sometimes get hooked).
When converting a query set to a list, it can be converted with ** list (QuerySet object)
**.
[^ 1]: Only specified fields can be extracted. Used for performance tuning. Conversely, you can use defer ()
to exclude the specified field.
Recommended Posts