Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
39f35d4b
Kaydet (Commit)
39f35d4b
authored
Agu 15, 2016
tarafından
Ian Foote
Kaydeden (comit)
Tim Graham
Agu 18, 2016
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #25871 -- Added expressions support to QuerySet.values().
üst
d4eefc7e
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
115 additions
and
7 deletions
+115
-7
query.py
django/db/models/query.py
+17
-4
querysets.txt
docs/ref/models/querysets.txt
+31
-3
1.11.txt
docs/releases/1.11.txt
+3
-0
test_queryset_values.py
tests/expressions/test_queryset_values.py
+64
-0
No files found.
django/db/models/query.py
Dosyayı görüntüle @
39f35d4b
...
...
@@ -678,14 +678,17 @@ class QuerySet(object):
using
=
self
.
db
return
RawQuerySet
(
raw_query
,
model
=
self
.
model
,
params
=
params
,
translations
=
translations
,
using
=
using
)
def
_values
(
self
,
*
fields
):
def
_values
(
self
,
*
fields
,
**
expressions
):
clone
=
self
.
_clone
()
if
expressions
:
clone
=
clone
.
annotate
(
**
expressions
)
clone
.
_fields
=
fields
clone
.
query
.
set_values
(
fields
)
return
clone
def
values
(
self
,
*
fields
):
clone
=
self
.
_values
(
*
fields
)
def
values
(
self
,
*
fields
,
**
expressions
):
fields
+=
tuple
(
expressions
)
clone
=
self
.
_values
(
*
fields
,
**
expressions
)
clone
.
_iterable_class
=
ValuesIterable
return
clone
...
...
@@ -697,7 +700,17 @@ class QuerySet(object):
if
flat
and
len
(
fields
)
>
1
:
raise
TypeError
(
"'flat' is not valid when values_list is called with more than one field."
)
clone
=
self
.
_values
(
*
fields
)
_fields
=
[]
expressions
=
{}
for
field
in
fields
:
if
hasattr
(
field
,
'resolve_expression'
):
field_id
=
str
(
id
(
field
))
expressions
[
field_id
]
=
field
_fields
.
append
(
field_id
)
else
:
_fields
.
append
(
field
)
clone
=
self
.
_values
(
*
_fields
,
**
expressions
)
clone
.
_iterable_class
=
FlatValuesListIterable
if
flat
else
ValuesListIterable
return
clone
...
...
docs/ref/models/querysets.txt
Dosyayı görüntüle @
39f35d4b
...
...
@@ -506,7 +506,7 @@ Examples (those after the first will only work on PostgreSQL)::
``values()``
~~~~~~~~~~~~
.. method:: values(*fields)
.. method:: values(*fields
, **expressions
)
Returns a ``QuerySet`` that returns dictionaries, rather than model instances,
when used as an iterable.
...
...
@@ -538,6 +538,23 @@ Example::
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>
The ``values()`` method also takes optional keyword arguments,
``**expressions``, which are passed through to :meth:`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('author', entries=Count('entry'))
<QuerySet [{'author': 1, 'entries': 20}, {'author': 1, 'entries': 13}]>
>>> Blog.objects.values('author').annotate(entries=Count('entry'))
<QuerySet [{'author': 1, 'entries': 33}]>
A few subtleties that are worth mentioning:
* If you have a field called ``foo`` that is a
...
...
@@ -603,6 +620,10 @@ You can also refer to fields on related models with reverse relations through
pronounced if you include multiple such fields in your ``values()`` query,
in which case all possible combinations will be returned.
.. versionchanged:: 1.11
Support for ``**expressions`` was added.
``values_list()``
~~~~~~~~~~~~~~~~~
...
...
@@ -610,11 +631,14 @@ You can also refer to fields on related models with reverse relations through
This is similar to ``values()`` except that instead of returning dictionaries,
it returns tuples when iterated over. Each tuple contains the value from the
respective field
passed into the ``values_list()`` call — so the first item is
the first field, etc. For example::
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')
[(1, 'First entry'), ...]
>>> from django.db.models.functions import Lower
>>> Entry.objects.values_list('id', Lower('headline'))
[(1, 'first entry'), ...]
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,
...
...
@@ -661,6 +685,10 @@ not having any author::
>>> Entry.objects.values_list('authors')
[('Noam Chomsky',), ('George Orwell',), (None,)]
.. versionchanged:: 1.11
Support for expressions in ``*fields`` was added.
``dates()``
~~~~~~~~~~~
...
...
docs/releases/1.11.txt
Dosyayı görüntüle @
39f35d4b
...
...
@@ -227,6 +227,9 @@ Models
to truncate :class:`~django.db.models.DateTimeField` to its time component
and exposed it through the :lookup:`time` lookup.
* Added support for expressions in :meth:`.QuerySet.values` and
:meth:`~.QuerySet.values_list`.
Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~
...
...
tests/expressions/test_queryset_values.py
0 → 100644
Dosyayı görüntüle @
39f35d4b
from
__future__
import
unicode_literals
from
django.db.models.aggregates
import
Sum
from
django.db.models.expressions
import
F
from
django.test
import
TestCase
from
.models
import
Company
,
Employee
class
ValuesExpressionsTests
(
TestCase
):
@classmethod
def
setUpTestData
(
cls
):
Company
.
objects
.
create
(
name
=
'Example Inc.'
,
num_employees
=
2300
,
num_chairs
=
5
,
ceo
=
Employee
.
objects
.
create
(
firstname
=
'Joe'
,
lastname
=
'Smith'
,
salary
=
10
)
)
Company
.
objects
.
create
(
name
=
'Foobar Ltd.'
,
num_employees
=
3
,
num_chairs
=
4
,
ceo
=
Employee
.
objects
.
create
(
firstname
=
'Frank'
,
lastname
=
'Meyer'
,
salary
=
20
)
)
Company
.
objects
.
create
(
name
=
'Test GmbH'
,
num_employees
=
32
,
num_chairs
=
1
,
ceo
=
Employee
.
objects
.
create
(
firstname
=
'Max'
,
lastname
=
'Mustermann'
,
salary
=
30
)
)
def
test_values_expression
(
self
):
self
.
assertSequenceEqual
(
Company
.
objects
.
values
(
salary
=
F
(
'ceo__salary'
)),
[{
'salary'
:
10
},
{
'salary'
:
20
},
{
'salary'
:
30
}],
)
def
test_values_expression_group_by
(
self
):
# values() applies annotate() first, so values selected are grouped by
# id, not firstname.
Employee
.
objects
.
create
(
firstname
=
'Joe'
,
lastname
=
'Jones'
,
salary
=
2
)
joes
=
Employee
.
objects
.
filter
(
firstname
=
'Joe'
)
self
.
assertSequenceEqual
(
joes
.
values
(
'firstname'
,
sum_salary
=
Sum
(
'salary'
))
.
order_by
(
'sum_salary'
),
[{
'firstname'
:
'Joe'
,
'sum_salary'
:
2
},
{
'firstname'
:
'Joe'
,
'sum_salary'
:
10
}],
)
self
.
assertSequenceEqual
(
joes
.
values
(
'firstname'
)
.
annotate
(
sum_salary
=
Sum
(
'salary'
)),
[{
'firstname'
:
'Joe'
,
'sum_salary'
:
12
}]
)
def
test_chained_values_with_expression
(
self
):
Employee
.
objects
.
create
(
firstname
=
'Joe'
,
lastname
=
'Jones'
,
salary
=
2
)
joes
=
Employee
.
objects
.
filter
(
firstname
=
'Joe'
)
.
values
(
'firstname'
)
self
.
assertSequenceEqual
(
joes
.
values
(
'firstname'
,
sum_salary
=
Sum
(
'salary'
)),
[{
'firstname'
:
'Joe'
,
'sum_salary'
:
12
}]
)
self
.
assertSequenceEqual
(
joes
.
values
(
sum_salary
=
Sum
(
'salary'
)),
[{
'sum_salary'
:
12
}]
)
def
test_values_list_expression
(
self
):
companies
=
Company
.
objects
.
values_list
(
'name'
,
F
(
'ceo__salary'
))
self
.
assertSequenceEqual
(
companies
,
[(
'Example Inc.'
,
10
),
(
'Foobar Ltd.'
,
20
),
(
'Test GmbH'
,
30
)])
def
test_values_list_expression_flat
(
self
):
companies
=
Company
.
objects
.
values_list
(
F
(
'ceo__salary'
),
flat
=
True
)
self
.
assertSequenceEqual
(
companies
,
(
10
,
20
,
30
))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment