Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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
Malcolm Tredinnick authored
5  django/core/exceptions.py
@@ -27,3 +27,8 @@ class MiddlewareNotUsed(Exception):
27 27
 class ImproperlyConfigured(Exception):
28 28
     "Django is somehow improperly configured"
29 29
     pass
  30
+
  31
+class FieldError(Exception):
  32
+    """Some kind of problem with a model field."""
  33
+    pass
  34
+
4  django/db/models/base.py
@@ -6,7 +6,7 @@
6 6
 import django.db.models.manipulators
7 7
 import django.db.models.manager
8 8
 from django.core import validators
9  
-from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
  9
+from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError
10 10
 from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
11 11
 from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField
12 12
 from django.db.models.query import delete_objects, Q
@@ -101,7 +101,7 @@ def __new__(cls, name, bases, attrs):
101 101
                 names = [f.name for f in new_class._meta.local_fields + new_class._meta.many_to_many]
102 102
                 for field in base._meta.local_fields:
103 103
                     if field.name in names:
104  
-                        raise TypeError('Local field %r in class %r clashes with field of similar name from abstract base class %r'
  104
+                        raise FieldError('Local field %r in class %r clashes with field of similar name from abstract base class %r'
105 105
                                 % (field.name, name, base.__name__))
106 106
                     new_class.add_to_class(field.name, field)
107 107
 
15  django/db/models/sql/query.py
@@ -19,6 +19,7 @@
19 19
 from django.db.models.sql.datastructures import Count, Date
20 20
 from django.db.models.fields import FieldDoesNotExist, Field, related
21 21
 from django.contrib.contenttypes import generic
  22
+from django.core.exceptions import FieldError
22 23
 from datastructures import EmptyResultSet
23 24
 
24 25
 try:
@@ -548,7 +549,7 @@ def find_ordering_name(self, name, opts, alias=None, default_order='ASC',
548 549
                 already_seen = {}
549 550
             join_tuple = tuple([tuple(j) for j in joins])
550 551
             if join_tuple in already_seen:
551  
-                raise TypeError('Infinite loop caused by ordering.')
  552
+                raise FieldError('Infinite loop caused by ordering.')
552 553
             already_seen[join_tuple] = True
553 554
 
554 555
             results = []
@@ -735,7 +736,7 @@ def add_filter(self, filter_expr, connector=AND, negate=False):
735 736
         arg, value = filter_expr
736 737
         parts = arg.split(LOOKUP_SEP)
737 738
         if not parts:
738  
-            raise TypeError("Cannot parse keyword query %r" % arg)
  739
+            raise FieldError("Cannot parse keyword query %r" % arg)
739 740
 
740 741
         # Work out the lookup type and remove it from 'parts', if necessary.
741 742
         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):
867 868
                 field, model, direct, m2m = opts.get_field_by_name(name)
868 869
             except FieldDoesNotExist:
869 870
                 names = opts.get_all_field_names()
870  
-                raise TypeError("Cannot resolve keyword %r into field. "
  871
+                raise FieldError("Cannot resolve keyword %r into field. "
871 872
                         "Choices are: %s" % (name, ", ".join(names)))
872 873
             if model:
873 874
                 # The field lives on a base class of the current model.
@@ -972,7 +973,7 @@ def setup_joins(self, names, opts, alias, dupe_multis):
972 973
                     joins.append([alias])
973 974
 
974 975
         if pos != len(names) - 1:
975  
-            raise TypeError("Join on field %r not permitted." % name)
  976
+            raise FieldError("Join on field %r not permitted." % name)
976 977
 
977 978
         return field, target, opts, joins
978 979
 
@@ -1033,7 +1034,7 @@ def add_ordering(self, *ordering):
1033 1034
             if not ORDER_PATTERN.match(item):
1034 1035
                 errors.append(item)
1035 1036
         if errors:
1036  
-            raise TypeError('Invalid order_by arguments: %s' % errors)
  1037
+            raise FieldError('Invalid order_by arguments: %s' % errors)
1037 1038
         if ordering:
1038 1039
             self.order_by.extend(ordering)
1039 1040
         else:
@@ -1228,7 +1229,7 @@ def as_sql(self):
1228 1229
                 for alias in alias_list:
1229 1230
                     if self.alias_map[alias][ALIAS_REFCOUNT]:
1230 1231
                         if table:
1231  
-                            raise TypeError('Updates can only access a single database table at a time.')
  1232
+                            raise FieldError('Updates can only access a single database table at a time.')
1232 1233
                         table = alias
1233 1234
         else:
1234 1235
             table = self.tables[0]
@@ -1271,7 +1272,7 @@ def add_update_values(self, values):
1271 1272
             field, model, direct, m2m = self.model._meta.get_field_by_name(name)
1272 1273
             if not direct or m2m:
1273 1274
                 # Can only update non-relation fields and foreign keys.
1274  
-                raise TypeError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field)
  1275
+                raise fieldError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field)
1275 1276
             if field.rel and isinstance(val, Model):
1276 1277
                 val = val.pk
1277 1278
             self.values.append((field.column, val))
2  tests/modeltests/custom_columns/models.py
@@ -71,7 +71,7 @@ class Meta:
71 71
 >>> Author.objects.filter(firstname__exact='John')
72 72
 Traceback (most recent call last):
73 73
     ...
74  
-TypeError: Cannot resolve keyword 'firstname' into field. Choices are: article, first_name, id, last_name
  74
+FieldError: Cannot resolve keyword 'firstname' into field. Choices are: article, first_name, id, last_name
75 75
 
76 76
 >>> a = Author.objects.get(last_name__exact='Smith')
77 77
 >>> a.first_name
5  tests/modeltests/field_subclassing/models.py
@@ -5,6 +5,7 @@
5 5
 from django.db import models
6 6
 from django.utils.encoding import force_unicode
7 7
 from django.core import serializers
  8
+from django.core.exceptions import FieldError
8 9
 
9 10
 class Small(object):
10 11
     """
@@ -50,7 +51,7 @@ def get_db_prep_lookup(self, lookup_type, value):
50 51
             return [force_unicode(v) for v in value]
51 52
         if lookup_type == 'isnull':
52 53
             return []
53  
-        raise TypeError('Invalid lookup type: %r' % lookup_type)
  54
+        raise FieldError('Invalid lookup type: %r' % lookup_type)
54 55
 
55 56
     def flatten_data(self, follow, obj=None):
56 57
         return {self.attname: force_unicode(self._get_val_from_obj(obj))}
@@ -94,7 +95,7 @@ def __unicode__(self):
94 95
 >>> MyModel.objects.filter(data__lt=s)
95 96
 Traceback (most recent call last):
96 97
 ...
97  
-TypeError: Invalid lookup type: 'lt'
  98
+FieldError: Invalid lookup type: 'lt'
98 99
 
99 100
 # Serialization works, too.
100 101
 >>> stream = serializers.serialize("json", MyModel.objects.all())
4  tests/modeltests/lookup/models.py
@@ -270,12 +270,12 @@ def __unicode__(self):
270 270
 >>> Article.objects.filter(pub_date_year='2005').count()
271 271
 Traceback (most recent call last):
272 272
     ...
273  
-TypeError: Cannot resolve keyword 'pub_date_year' into field. Choices are: headline, id, pub_date
  273
+FieldError: Cannot resolve keyword 'pub_date_year' into field. Choices are: headline, id, pub_date
274 274
 
275 275
 >>> Article.objects.filter(headline__starts='Article')
276 276
 Traceback (most recent call last):
277 277
     ...
278  
-TypeError: Join on field 'headline' not permitted.
  278
+FieldError: Join on field 'headline' not permitted.
279 279
 
280 280
 # Create some articles with a bit more interesting headlines for testing field lookups:
281 281
 >>> now = datetime.now()
4  tests/modeltests/many_to_one/models.py
@@ -179,13 +179,13 @@ class Meta:
179 179
 >>> Article.objects.filter(reporter_id__exact=1)
180 180
 Traceback (most recent call last):
181 181
     ...
182  
-TypeError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter
  182
+FieldError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter
183 183
 
184 184
 # You need to specify a comparison clause
185 185
 >>> Article.objects.filter(reporter_id=1)
186 186
 Traceback (most recent call last):
187 187
     ...
188  
-TypeError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter
  188
+FieldError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter
189 189
 
190 190
 # You can also instantiate an Article by passing
191 191
 # the Reporter's ID instead of a Reporter object.
2  tests/modeltests/model_inheritance/models.py
@@ -148,7 +148,7 @@ def __unicode__(self):
148 148
 >>> Restaurant.objects.filter(supplier__name='foo')
149 149
 Traceback (most recent call last):
150 150
     ...
151  
-TypeError: Cannot resolve keyword 'supplier' into field. Choices are: address, id, italianrestaurant, lot, name, place_ptr, provider, rating, serves_hot_dogs, serves_pizza
  151
+FieldError: Cannot resolve keyword 'supplier' into field. Choices are: address, id, italianrestaurant, lot, name, place_ptr, provider, rating, serves_hot_dogs, serves_pizza
152 152
 
153 153
 # Parent fields can be used directly in filters on the child model.
154 154
 >>> Restaurant.objects.filter(name='Demon Dogs')
2  tests/modeltests/reverse_lookup/models.py
@@ -55,5 +55,5 @@ def __unicode__(self):
55 55
 >>> Poll.objects.get(choice__name__exact="This is the answer")
56 56
 Traceback (most recent call last):
57 57
     ...
58  
-TypeError: Cannot resolve keyword 'choice' into field. Choices are: creator, id, poll_choice, question, related_choice
  58
+FieldError: Cannot resolve keyword 'choice' into field. Choices are: creator, id, poll_choice, question, related_choice
59 59
 """}
2  tests/regressiontests/null_queries/models.py
@@ -37,7 +37,7 @@ def __unicode__(self):
37 37
 >>> Choice.objects.filter(foo__exact=None)
38 38
 Traceback (most recent call last):
39 39
 ...
40  
-TypeError: Cannot resolve keyword 'foo' into field. Choices are: choice, id, poll
  40
+FieldError: Cannot resolve keyword 'foo' into field. Choices are: choice, id, poll
41 41
 
42 42
 # Can't use None on anything other than __exact
43 43
 >>> Choice.objects.filter(id__gt=None)
2  tests/regressiontests/queries/models.py
@@ -394,7 +394,7 @@ class Meta:
394 394
 >>> LoopX.objects.all()
395 395
 Traceback (most recent call last):
396 396
 ...
397  
-TypeError: Infinite loop caused by ordering.
  397
+FieldError: Infinite loop caused by ordering.
398 398
 
399 399
 # If the remote model does not have a default ordering, we order by its 'id'
400 400
 # field.

0 notes on commit 014373b

Please sign in to comment.
Something went wrong with that request. Please try again.