1
0
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:
Malcolm Tredinnick 2007-10-15 02:54:30 +00:00
parent 4c4341f012
commit 70d5e32e13
3 changed files with 53 additions and 5 deletions

View File

@ -391,17 +391,22 @@ class ValuesQuerySet(QuerySet):
# 'fields' is used to configure the query, whilst field_names is stored
# in this object for use by iterator().
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:
fields = [self.model._meta.get_field(f, many_to_many=False)
for f in self._fields]
try:
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
else:
fields = []
field_names = []
for f in self._fields:
if f in [field.name for field in self.model._meta.fields]:
fields.append(self.model._meta.get_field(f,
many_to_many=False))
if f in all:
fields.append(all[f])
field_names.append(f)
elif not self.query.extra_select.has_key(f):
raise FieldDoesNotExist('%s has no field named %r'

View File

@ -583,6 +583,30 @@ Example::
>>> Blog.objects.values('id', 'name')
[{'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
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

View File

@ -334,5 +334,24 @@ Bug #3037
Bug #5321
>>> Note.objects.values('misc').distinct().order_by('note', '-misc')
[{'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}]
"""}