Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

queryset-refactor: Fixed #6664. Calling list() no longer swallows fie…

…ld errors.

This is slightly backwards incompatible with previous behaviour if you were
doing Tricky Stuff(tm) -- the exception type has changed if you try to create a
bad queryset.


git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7163 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 014373b459e0925ad757a56d9b4f049bc4f776fc 1 parent fc4c0f7
@malcolmt malcolmt authored
View
5 django/core/exceptions.py
@@ -27,3 +27,8 @@ class MiddlewareNotUsed(Exception):
class ImproperlyConfigured(Exception):
"Django is somehow improperly configured"
pass
+
+class FieldError(Exception):
+ """Some kind of problem with a model field."""
+ pass
+
View
4 django/db/models/base.py
@@ -6,7 +6,7 @@
import django.db.models.manipulators
import django.db.models.manager
from django.core import validators
-from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
+from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError
from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField
from django.db.models.query import delete_objects, Q
@@ -101,7 +101,7 @@ def __new__(cls, name, bases, attrs):
names = [f.name for f in new_class._meta.local_fields + new_class._meta.many_to_many]
for field in base._meta.local_fields:
if field.name in names:
- raise TypeError('Local field %r in class %r clashes with field of similar name from abstract base class %r'
+ raise FieldError('Local field %r in class %r clashes with field of similar name from abstract base class %r'
% (field.name, name, base.__name__))
new_class.add_to_class(field.name, field)
View
15 django/db/models/sql/query.py
@@ -19,6 +19,7 @@
from django.db.models.sql.datastructures import Count, Date
from django.db.models.fields import FieldDoesNotExist, Field, related
from django.contrib.contenttypes import generic
+from django.core.exceptions import FieldError
from datastructures import EmptyResultSet
try:
@@ -548,7 +549,7 @@ def find_ordering_name(self, name, opts, alias=None, default_order='ASC',
already_seen = {}
join_tuple = tuple([tuple(j) for j in joins])
if join_tuple in already_seen:
- raise TypeError('Infinite loop caused by ordering.')
+ raise FieldError('Infinite loop caused by ordering.')
already_seen[join_tuple] = True
results = []
@@ -735,7 +736,7 @@ def add_filter(self, filter_expr, connector=AND, negate=False):
arg, value = filter_expr
parts = arg.split(LOOKUP_SEP)
if not parts:
- raise TypeError("Cannot parse keyword query %r" % arg)
+ raise FieldError("Cannot parse keyword query %r" % arg)
# Work out the lookup type and remove it from 'parts', if necessary.
if len(parts) == 1 or parts[-1] not in self.query_terms:
@@ -867,7 +868,7 @@ def setup_joins(self, names, opts, alias, dupe_multis):
field, model, direct, m2m = opts.get_field_by_name(name)
except FieldDoesNotExist:
names = opts.get_all_field_names()
- raise TypeError("Cannot resolve keyword %r into field. "
+ raise FieldError("Cannot resolve keyword %r into field. "
"Choices are: %s" % (name, ", ".join(names)))
if model:
# The field lives on a base class of the current model.
@@ -972,7 +973,7 @@ def setup_joins(self, names, opts, alias, dupe_multis):
joins.append([alias])
if pos != len(names) - 1:
- raise TypeError("Join on field %r not permitted." % name)
+ raise FieldError("Join on field %r not permitted." % name)
return field, target, opts, joins
@@ -1033,7 +1034,7 @@ def add_ordering(self, *ordering):
if not ORDER_PATTERN.match(item):
errors.append(item)
if errors:
- raise TypeError('Invalid order_by arguments: %s' % errors)
+ raise FieldError('Invalid order_by arguments: %s' % errors)
if ordering:
self.order_by.extend(ordering)
else:
@@ -1228,7 +1229,7 @@ def as_sql(self):
for alias in alias_list:
if self.alias_map[alias][ALIAS_REFCOUNT]:
if table:
- raise TypeError('Updates can only access a single database table at a time.')
+ raise FieldError('Updates can only access a single database table at a time.')
table = alias
else:
table = self.tables[0]
@@ -1271,7 +1272,7 @@ def add_update_values(self, values):
field, model, direct, m2m = self.model._meta.get_field_by_name(name)
if not direct or m2m:
# Can only update non-relation fields and foreign keys.
- raise TypeError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field)
+ raise fieldError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field)
if field.rel and isinstance(val, Model):
val = val.pk
self.values.append((field.column, val))
View
2  tests/modeltests/custom_columns/models.py
@@ -71,7 +71,7 @@ class Meta:
>>> Author.objects.filter(firstname__exact='John')
Traceback (most recent call last):
...
-TypeError: Cannot resolve keyword 'firstname' into field. Choices are: article, first_name, id, last_name
+FieldError: Cannot resolve keyword 'firstname' into field. Choices are: article, first_name, id, last_name
>>> a = Author.objects.get(last_name__exact='Smith')
>>> a.first_name
View
5 tests/modeltests/field_subclassing/models.py
@@ -5,6 +5,7 @@
from django.db import models
from django.utils.encoding import force_unicode
from django.core import serializers
+from django.core.exceptions import FieldError
class Small(object):
"""
@@ -50,7 +51,7 @@ def get_db_prep_lookup(self, lookup_type, value):
return [force_unicode(v) for v in value]
if lookup_type == 'isnull':
return []
- raise TypeError('Invalid lookup type: %r' % lookup_type)
+ raise FieldError('Invalid lookup type: %r' % lookup_type)
def flatten_data(self, follow, obj=None):
return {self.attname: force_unicode(self._get_val_from_obj(obj))}
@@ -94,7 +95,7 @@ def __unicode__(self):
>>> MyModel.objects.filter(data__lt=s)
Traceback (most recent call last):
...
-TypeError: Invalid lookup type: 'lt'
+FieldError: Invalid lookup type: 'lt'
# Serialization works, too.
>>> stream = serializers.serialize("json", MyModel.objects.all())
View
4 tests/modeltests/lookup/models.py
@@ -270,12 +270,12 @@ def __unicode__(self):
>>> Article.objects.filter(pub_date_year='2005').count()
Traceback (most recent call last):
...
-TypeError: Cannot resolve keyword 'pub_date_year' into field. Choices are: headline, id, pub_date
+FieldError: Cannot resolve keyword 'pub_date_year' into field. Choices are: headline, id, pub_date
>>> Article.objects.filter(headline__starts='Article')
Traceback (most recent call last):
...
-TypeError: Join on field 'headline' not permitted.
+FieldError: Join on field 'headline' not permitted.
# Create some articles with a bit more interesting headlines for testing field lookups:
>>> now = datetime.now()
View
4 tests/modeltests/many_to_one/models.py
@@ -179,13 +179,13 @@ class Meta:
>>> Article.objects.filter(reporter_id__exact=1)
Traceback (most recent call last):
...
-TypeError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter
+FieldError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter
# You need to specify a comparison clause
>>> Article.objects.filter(reporter_id=1)
Traceback (most recent call last):
...
-TypeError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter
+FieldError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter
# You can also instantiate an Article by passing
# the Reporter's ID instead of a Reporter object.
View
2  tests/modeltests/model_inheritance/models.py
@@ -148,7 +148,7 @@ def __unicode__(self):
>>> Restaurant.objects.filter(supplier__name='foo')
Traceback (most recent call last):
...
-TypeError: Cannot resolve keyword 'supplier' into field. Choices are: address, id, italianrestaurant, lot, name, place_ptr, provider, rating, serves_hot_dogs, serves_pizza
+FieldError: Cannot resolve keyword 'supplier' into field. Choices are: address, id, italianrestaurant, lot, name, place_ptr, provider, rating, serves_hot_dogs, serves_pizza
# Parent fields can be used directly in filters on the child model.
>>> Restaurant.objects.filter(name='Demon Dogs')
View
2  tests/modeltests/reverse_lookup/models.py
@@ -55,5 +55,5 @@ def __unicode__(self):
>>> Poll.objects.get(choice__name__exact="This is the answer")
Traceback (most recent call last):
...
-TypeError: Cannot resolve keyword 'choice' into field. Choices are: creator, id, poll_choice, question, related_choice
+FieldError: Cannot resolve keyword 'choice' into field. Choices are: creator, id, poll_choice, question, related_choice
"""}
View
2  tests/regressiontests/null_queries/models.py
@@ -37,7 +37,7 @@ def __unicode__(self):
>>> Choice.objects.filter(foo__exact=None)
Traceback (most recent call last):
...
-TypeError: Cannot resolve keyword 'foo' into field. Choices are: choice, id, poll
+FieldError: Cannot resolve keyword 'foo' into field. Choices are: choice, id, poll
# Can't use None on anything other than __exact
>>> Choice.objects.filter(id__gt=None)
View
2  tests/regressiontests/queries/models.py
@@ -394,7 +394,7 @@ class Meta:
>>> LoopX.objects.all()
Traceback (most recent call last):
...
-TypeError: Infinite loop caused by ordering.
+FieldError: Infinite loop caused by ordering.
# If the remote model does not have a default ordering, we order by its 'id'
# field.
Please sign in to comment.
Something went wrong with that request. Please try again.