Django

Code

Changeset 6516

Show
Ignore:
Timestamp:
10/14/07 21:54:30 (9 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Made the use of values() for ForeignKey? fields consistent
and documented this feature. Refs #4358.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/django/db/models/query.py

    r6512 r6516  
    392392        # in this object for use by iterator(). 
    393393        if self._fields: 
     394            opts = self.model._meta 
     395            all = dict([(field.column, field) for field in opts.fields]) 
     396            all.update([(field.name, field) for field in opts.fields]) 
    394397            if not self.query.extra_select: 
    395                 fields = [self.model._meta.get_field(f, many_to_many=False) 
    396                         for f in self._fields] 
     398                try: 
     399                    fields = [all[f] for f in self._fields] 
     400                except KeyError, e: 
     401                    raise FieldDoesNotExist('%s has no field named %r' 
     402                                % (opts.object_name, e.args[0])) 
    397403                field_names = self._fields 
    398404            else: 
     
    400406                field_names = [] 
    401407                for f in self._fields: 
    402                     if f in [field.name for field in self.model._meta.fields]: 
    403                         fields.append(self.model._meta.get_field(f, 
    404                                 many_to_many=False)) 
     408                    if f in all: 
     409                        fields.append(all[f]) 
    405410                        field_names.append(f) 
    406411                    elif not self.query.extra_select.has_key(f): 
  • django/branches/queryset-refactor/docs/db-api.txt

    r6513 r6516  
    583583    >>> Blog.objects.values('id', 'name') 
    584584    [{'id': 1, 'name': 'Beatles Blog'}] 
     585 
     586A couple of subtleties that are worth mentioning: 
     587 
     588    * The ``values()`` method does not return anything for ``ManyToManyField`` 
     589      attributes and will raise an error if you try to pass in this type of 
     590      field to it. 
     591    * If you have a field called ``foo`` that is a ``ForeignKey``, the default 
     592      ``values()`` call will return a dictionary key called ``foo_id``, since 
     593      this is the name of the hidden model attribute that stores the actual 
     594      value (the ``foo`` attribute refers to the related model). When you are 
     595      calling ``values()`` and passing in field names, you can pass in either 
     596      ``foo`` or ``foo_id`` and you will get back the same thing (the 
     597      dictionary key will match the field name you passed in). 
     598 
     599      For example:: 
     600 
     601        >>> Entry.objects.values() 
     602        [{'blog_id: 1, 'headline': u'First Entry', ...}, ...] 
     603 
     604        >>> Entry.objects.values('blog') 
     605        [{'blog': 1}, ...] 
     606 
     607        >>> Entry.objects.values('blog_id') 
     608        [{'blog_id': 1}, ...] 
    585609 
    586610A ``ValuesQuerySet`` is useful when you know you're only going to need values 
  • django/branches/queryset-refactor/tests/regressiontests/queries/models.py

    r6515 r6516  
    335335>>> Note.objects.values('misc').distinct().order_by('note', '-misc') 
    336336[{'misc': u'foo'}, {'misc': u'bar'}] 
     337 
     338Bug #4358 
     339If you don't pass any fields to values(), relation fields are returned as 
     340"foo_id" keys, not "foo". For consistency, you should be able to pass "foo_id" 
     341in the fields list and have it work, too. We actually allow both "foo" and 
     342"foo_id". 
     343 
     344# The *_id version is returned by default. 
     345>>> 'note_id' in ExtraInfo.objects.values()[0] 
     346True 
     347 
     348# You can also pass it in explicitly. 
     349>>> ExtraInfo.objects.values('note_id') 
     350[{'note_id': 1}, {'note_id': 2}] 
     351 
     352# ...or use the field name. 
     353>>> ExtraInfo.objects.values('note') 
     354[{'note': 1}, {'note': 2}] 
     355 
    337356"""} 
    338357