At what point do exceptions occur when using Django ORM

A fairly simple example - I have some Django code that starts with a set of requests ...

queryset = MyModel.objects.all() 

Later it performs various filtering, depending on some configurable parameters ...

 if something: queryset = self.queryset.filter(foo=some_foo) if another_thing: queryset = self.queryset.filter(bar=some_bar) 

And finally, he performs a search ...

 try: obj = queryset.get() except ObjectDoesNotExist: raise ValidationError('Does not exist') 

Now, due to the flexible filtering method, it is possible that some_foo or some_bar may not be of the appropriate type (for example, we could get an empty string trying to filter against an integer field.), So it is possible that this code will complete raising a TypeError or ValueError .

This is good, and I can handle this case properly, but what is not clear to me from the ORM contract, at what point should I expect these exceptions to be raised.

  • Will this be done in the .filter() statement? ...
  • ... or in the .get() statement? ...
  • ... or is underspecified, and am I treating it as capable of occurring on any of them? (For example, maybe, depending on the database backed implementation?)
+6
source share
1 answer

To answer the original question, when calling for filtering, when creating a new set of queries, FieldError and ValueError arise:

 >>> a = Account.objects.all() >>> a = a.filter(id=3) >>> a = a.filter(no_exist=3) <snip> FieldError: Cannot resolve keyword 'no_exist' into field. Choices are: active, created_on, group, id, ... >>> a = Account.objects.all() >>> a = a.filter(id='abc') ValueError: invalid literal for int() with base 10: 'abc' 

I will also add that this pattern seems confusing to me, as filter usually used to return the / iterable list for models, and not as for get . For clarity and simplification of exception handling, I would suggest this pattern:

 kwargs = {} if something: kwargs['foo'] = some_foo if another_thing: kwargs['bar'] = some_bar # handle if kwargs is empty try: obj = MyModel.objects.get(**kwargs) except (FieldError, ValueError, ObjectDoesNotExist): raise ValidationError('Does not exist') 

Another added benefit is that IIRC, handling cloning requests is relatively expensive, so you ignore this overhead and at the same time make the code cleaner. Returning to your question, there is no question with this scheme where the exception will occur.

+1
source

All Articles