mirror of
https://github.com/django/django.git
synced 2025-07-06 10:49:17 +00:00
queryset-refactor: Made the use of values() for ForeignKey fields consistent
and documented this feature. Refs #4358. git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6516 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
4c4341f012
commit
70d5e32e13
@ -391,17 +391,22 @@ class ValuesQuerySet(QuerySet):
|
|||||||
# 'fields' is used to configure the query, whilst field_names is stored
|
# 'fields' is used to configure the query, whilst field_names is stored
|
||||||
# in this object for use by iterator().
|
# in this object for use by iterator().
|
||||||
if self._fields:
|
if self._fields:
|
||||||
|
opts = self.model._meta
|
||||||
|
all = dict([(field.column, field) for field in opts.fields])
|
||||||
|
all.update([(field.name, field) for field in opts.fields])
|
||||||
if not self.query.extra_select:
|
if not self.query.extra_select:
|
||||||
fields = [self.model._meta.get_field(f, many_to_many=False)
|
try:
|
||||||
for f in self._fields]
|
fields = [all[f] for f in self._fields]
|
||||||
|
except KeyError, e:
|
||||||
|
raise FieldDoesNotExist('%s has no field named %r'
|
||||||
|
% (opts.object_name, e.args[0]))
|
||||||
field_names = self._fields
|
field_names = self._fields
|
||||||
else:
|
else:
|
||||||
fields = []
|
fields = []
|
||||||
field_names = []
|
field_names = []
|
||||||
for f in self._fields:
|
for f in self._fields:
|
||||||
if f in [field.name for field in self.model._meta.fields]:
|
if f in all:
|
||||||
fields.append(self.model._meta.get_field(f,
|
fields.append(all[f])
|
||||||
many_to_many=False))
|
|
||||||
field_names.append(f)
|
field_names.append(f)
|
||||||
elif not self.query.extra_select.has_key(f):
|
elif not self.query.extra_select.has_key(f):
|
||||||
raise FieldDoesNotExist('%s has no field named %r'
|
raise FieldDoesNotExist('%s has no field named %r'
|
||||||
|
@ -583,6 +583,30 @@ Example::
|
|||||||
>>> Blog.objects.values('id', 'name')
|
>>> Blog.objects.values('id', 'name')
|
||||||
[{'id': 1, 'name': 'Beatles Blog'}]
|
[{'id': 1, 'name': 'Beatles Blog'}]
|
||||||
|
|
||||||
|
A couple of subtleties that are worth mentioning:
|
||||||
|
|
||||||
|
* The ``values()`` method does not return anything for ``ManyToManyField``
|
||||||
|
attributes and will raise an error if you try to pass in this type of
|
||||||
|
field to it.
|
||||||
|
* If you have a field called ``foo`` that is a ``ForeignKey``, the default
|
||||||
|
``values()`` call will return a dictionary key called ``foo_id``, since
|
||||||
|
this is the name of the hidden model attribute that stores the actual
|
||||||
|
value (the ``foo`` attribute refers to the related model). When you are
|
||||||
|
calling ``values()`` and passing in field names, you can pass in either
|
||||||
|
``foo`` or ``foo_id`` and you will get back the same thing (the
|
||||||
|
dictionary key will match the field name you passed in).
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
>>> Entry.objects.values()
|
||||||
|
[{'blog_id: 1, 'headline': u'First Entry', ...}, ...]
|
||||||
|
|
||||||
|
>>> Entry.objects.values('blog')
|
||||||
|
[{'blog': 1}, ...]
|
||||||
|
|
||||||
|
>>> Entry.objects.values('blog_id')
|
||||||
|
[{'blog_id': 1}, ...]
|
||||||
|
|
||||||
A ``ValuesQuerySet`` is useful when you know you're only going to need values
|
A ``ValuesQuerySet`` 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
|
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
|
functionality of a model instance object. It's more efficient to select only
|
||||||
|
@ -334,5 +334,24 @@ Bug #3037
|
|||||||
Bug #5321
|
Bug #5321
|
||||||
>>> Note.objects.values('misc').distinct().order_by('note', '-misc')
|
>>> Note.objects.values('misc').distinct().order_by('note', '-misc')
|
||||||
[{'misc': u'foo'}, {'misc': u'bar'}]
|
[{'misc': u'foo'}, {'misc': u'bar'}]
|
||||||
|
|
||||||
|
Bug #4358
|
||||||
|
If you don't pass any fields to values(), relation fields are returned as
|
||||||
|
"foo_id" keys, not "foo". For consistency, you should be able to pass "foo_id"
|
||||||
|
in the fields list and have it work, too. We actually allow both "foo" and
|
||||||
|
"foo_id".
|
||||||
|
|
||||||
|
# The *_id version is returned by default.
|
||||||
|
>>> 'note_id' in ExtraInfo.objects.values()[0]
|
||||||
|
True
|
||||||
|
|
||||||
|
# You can also pass it in explicitly.
|
||||||
|
>>> ExtraInfo.objects.values('note_id')
|
||||||
|
[{'note_id': 1}, {'note_id': 2}]
|
||||||
|
|
||||||
|
# ...or use the field name.
|
||||||
|
>>> ExtraInfo.objects.values('note')
|
||||||
|
[{'note': 1}, {'note': 2}]
|
||||||
|
|
||||||
"""}
|
"""}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user