概述
values()
¶
values
(
*fields,
**expressions)
¶
Returns a QuerySet
that returns dictionaries, rather than model instances, when used as an iterable.
Each of those dictionaries represents an object, with the keys corresponding to the attribute names of model objects.
values()
with the normal model objects:
# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
<QuerySet [<Blog: Beatles Blog>]>
# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
The values()
method takes optional positional arguments, *fields
, which specify field names to which the SELECT
should be limited. If you specify the fields, each dictionary will contain only the field keys/values for the fields you specify. If you don’t specify the fields, each dictionary will contain a key and value for every field in the database table.
>>> Blog.objects.values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>
values()
method also takes optional keyword arguments,
**expressions
, which are passed through to
annotate()
:
>>> from django.db.models.functions import Lower
>>> Blog.objects.values(lower_name=Lower('name'))
<QuerySet [{'lower_name': 'beatles blog'}]>
An aggregate within a values()
clause is applied before other arguments within the same values()
clause. If you need to group by another value, add it to an earlier values()
clause instead. For example:
>>> from django.db.models import Count
>>> Blog.objects.values('entry__authors', entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]>
>>> Blog.objects.values('entry__authors').annotate(entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 33}]>
A few subtleties that are worth mentioning:
If you have a field called
foo
that is aForeignKey
, the defaultvalues()
call will return a dictionary key calledfoo_id
, since this is the name of the hidden model attribute that stores the actual value (thefoo
attribute refers to the related model). When you are callingvalues()
and passing in field names, you can pass in eitherfoo
orfoo_id
and you will get back the same thing (the dictionary key will match the field name you passed in).For example:这是外键的例子,value()函数返回外键在数据库中的id,数据字典的key有两种: blog或blog_id,但对应的值是一样的。>>> Entry.objects.values() <QuerySet [{'blog_id': 1, 'headline': 'First Entry', ...}, ...]> >>> Entry.objects.values('blog') <QuerySet [{'blog': 1}, ...]> >>> Entry.objects.values('blog_id') <QuerySet [{'blog_id': 1}, ...]>
When using
values()
together withdistinct()
, be aware that ordering can affect the results. See the note indistinct()
for details.If you use a
values()
clause after anextra()
call, any fields defined by aselect
argument in theextra()
must be explicitly included in thevalues()
call. Anyextra()
call made after avalues()
call will have its extra selected fields ignored.Calling
only()
anddefer()
aftervalues()
doesn’t make sense, so doing so will raise aNotImplementedError
.
It is useful when you know you’re only going to need values from a small number of the available fields and you won’t need the functionality of a model instance object. It’s more efficient to select only the fields you need to use.
Finally, note that you can call filter()
, order_by()
, etc. after the values()
call, that means that these two calls are identical:
Blog.objects.values().order_by('id')
Blog.objects.order_by('id').values()
The people who made Django prefer to put all the SQL-affecting methods first, followed (optionally) by any output-affecting methods (such as values()
), but it doesn’t really matter. This is your chance to really flaunt your individualism.
You can also refer to fields on related models with reverse relations through OneToOneField
, ForeignKey
and ManyToManyField
attributes:
>>> Blog.objects.values('name', 'entry__headline')
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
{'name': 'My blog', 'entry__headline': 'Another entry'}, ...]>
Warning
Because ManyToManyField
attributes and reverse relations can have multiple related rows, including these can have a multiplier effect on the size of your result set. This will be especially pronounced if you include multiple such fields in your values()
query, in which case all possible combinations will be returned.
Support for **expressions
was added.
values_list()
¶
values_list
(
*fields,
flat=False,
named=False)
¶
values()
except that instead of returning dictionaries, it returns tuples when iterated over. Each tuple contains the value from the respective field or expression passed into the
values_list()
call — so the first item is the first field, etc. For example:
>>> Entry.objects.values_list('id', 'headline')
<QuerySet [(1, 'First entry'), ...]>
>>> from django.db.models.functions import Lower
>>> Entry.objects.values_list('id', Lower('headline'))
<QuerySet [(1, 'first entry'), ...]>
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')
<QuerySet[(1,), (2,), (3,), ...]>
>>> Entry.objects.values_list('id', flat=True).order_by('id')
<QuerySet [1, 2, 3, ...]>
It is an error to pass in flat
when there is more than one field.
You can pass named=True
to get results as a namedtuple()
:
>>> Entry.objects.values_list('id', 'headline', named=True)
<QuerySet [Row(id=1, headline='First entry'), ...]>
Using a named tuple may make use of the results more readable, at the expense of a small performance penalty for transforming the results into a named tuple.
If you don’t pass any values to values_list()
, it will return all the fields in the model, in the order they were declared.
A common need is to get a specific field value of a certain model instance. To achieve that, use values_list()
followed by a get()
call:
>>> Entry.objects.values_list('headline', flat=True).get(pk=1)
'First entry'
values()
and values_list()
are both intended as optimizations for a specific use case: retrieving a subset of data without the overhead of creating a model instance. This metaphor falls apart when dealing with many-to-many and other multivalued relations (such as the one-to-many relation of a reverse foreign key) because the “one row, one object” assumption doesn’t hold.
For example, notice the behavior when querying across a ManyToManyField
:
>>> Author.objects.values_list('name', 'entry__headline')
<QuerySet [('Noam Chomsky', 'Impressions of Gaza'),
('George Orwell', 'Why Socialists Do Not Believe in Fun'),
('George Orwell', 'In Defence of English Cooking'),
('Don Quixote', None)]>
Authors with multiple entries appear multiple times and authors without any entries have None
for the entry headline.
Similarly, when querying a reverse foreign key, None
appears for entries not having any author:
>>> Entry.objects.values_list('authors')
<QuerySet [('Noam Chomsky',), ('George Orwell',), (None,)]>
Support for expressions in *fields
was added.
The named
parameter was added.
最后
以上就是从容飞机为你收集整理的django以字典或元组形式输出数据库结果集,可以选择输出特定列的结果的全部内容,希望文章能够帮你解决django以字典或元组形式输出数据库结果集,可以选择输出特定列的结果所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复